一周两个设计模式—设计模式策略模式(第七周)

举报
浮生闲半日 发表于 2021/11/29 14:42:10 2021/11/29
【摘要】 业务背景:小犬通过几次帮助天庭咖啡厅解决系统开发中的问题,现在已经是名声在外了,这不今天又有人来寻求帮助了,原来是天庭最近正在举办第一届小学生编程比赛,这不请小犬来特邀嘉宾来审核选手的代码,小犬高高兴兴的接受了这个邀请。比赛中:小犬闲来无事开始观察选手的代码,其中有一道题是这样的有十个选项,点击每一个都对应着一种计算方式,请大家实现,粗略看了一下,大部分选手都是定义了5个按钮,然后点击一下调...

业务背景:

小犬通过几次帮助天庭咖啡厅解决系统开发中的问题,现在已经是名声在外了,这不今天又有人来寻求帮助了,原来是天庭最近正在举办
第一届小学生编程比赛,这不请小犬来特邀嘉宾来审核选手的代码,小犬高高兴兴的接受了这个邀请。

比赛中:小犬闲来无事开始观察选手的代码,其中有一道题是这样的有十个选项,点击每一个都对应着一种计算方式,请大家实现,粗略
看了一下,大部分选手都是定义了5个按钮,然后点击一下调用了一个方法,问题不大,突然有一个人的代码突然让小犬眼前一亮。

代码如下:

抽象了计算方法:

interface Calculate {

    fun calculate(num:Int)

}

实例化方法:

class CalculateFirst:Calculate{
    override fun calculate(num: Int) {
        Log.v("=======","第一种计算方法")
    }
}

以此类推实例化了五个方法。

管理类:

class StrategyManager constructor(var num: Int, var calculate: Calculate) {
    fun calculate() {
        calculate.calculate(num)
    }
}

具体实现方式:

 var calculate = CalculateThird()
 strategyManager = StrategyManager(25,calculate)
 strategyManager.calculate()

就是这些代码让他眼前一亮,为什么呢?听它慢慢道来

首先这么肯定显得多了很多的类,但是首先这么写直接把实现逻辑给分离了,并且在实际开发中使用者不应该关心计算的实现
方式,只关心结果,同时算法修改后对使用者来说是无感知的,添加了中间的管理类来增加扩展性比如除了原始计算还需要别的需求,
这样主代码中就会很清爽,不会 冗余,并且这么写的话维护性、扩展性都会很好,也让程序结构更加灵活了,对修改关闭对扩展开放。

但是这么实现同时也有缺点:需要使用者对每一种实现都得知道是做什么的,才能正确调用否则会有问题。

说了这么多,可以介绍一下策略模式了:

定义:

实现某一个功能有多条途径,每一条途径对应一种算法,此时我们可以使用一种设计模式来实现灵活地选择解决途径,
也能够方便地增加新的解决途径。

角色:

(管理类):环境类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
 
(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。

(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

实现代码:

 如上代码所示。

优点:

算法可以自由切换

避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)

扩展性良好,增加一个策略只需实现接口即可

缺点:

策略类数量会增多,每个策略都是一个类,复用的可能性很小

所有的策略类都需要对外暴露
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。