IOS开发

iOS - 策略模式

2018-10-29  本文已影响0人  Longshihua

定义

策略模式是一种比较简单的模式,也叫政策模式。定义一系列的算法,把它们一个个封装起来,并且使它们可相互替代。

类图

屏幕快照 2018-10-29 上午10.57.40.png

策略模式的三个角色

策略模式使用的是面向对象的继承和多态机制,一起来了解一下策略模式中的三个角色:

Context封装角色

简单理解为上下文,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

Strategy抽象策略角色

策略,算法家族的抽象,通常为接口,定义每个策略或者算法必须具有的方法和属性。

ConcreteStrategy具体策略角色

DEMO

看一个简单的例子,源于这里

1、定义策略,Swift中我们基本上使用protocol,也可以使用基类,在基类中定义抽象操作

protocol PrintStrategy {
    func print(_ string: String) -> String
}

2、遵守协议或者继承基类,实现具体的策略

final class UpperCaseStrategy: PrintStrategy {
    func print(_ string: String) -> String {
        return string.uppercased()
    }
}
 
final class LowerCaseStrategy: PrintStrategy {
    func print(_ string:String) -> String {
        return string.lowercased()
    }
}

3、构造封装类,即上下文,根据需要创建对应的策略

final class Printer {
    private let strategy: PrintStrategy
 
    func print(_ string: String) -> String {
        return self.strategy.print(string)
    }
 
    init(strategy: PrintStrategy) {
        self.strategy = strategy
    }
}

4、在具体的场景中使用具体的策略

var lower = Printer(strategy: LowerCaseStrategy())
lower.print("O tempora, o mores!")
 
var upper = Printer(strategy: UpperCaseStrategy())
upper.print("O tempora, o mores!")

使用场景

1、多个类只有在算法或者行为稍有不同的场景

2、算法需要自由切换的场景

例如:算法的选择是由使用者决定的,或者算法始终在进化,特别是一些站在技术前沿的行业,连业务专家都无法给你保证这样的系统规则能够存在多长时间,在这种情况下策略模式是个不错的选择。

3、需要屏蔽算法规则的场景

只需要知道一个算法的名字,而不需要知道其他的内容。

优缺点

优点

1、算法可以自由切换

这是策略模式本身定义的,只要实现抽象策略,它就成为了策略家族的一员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。

2、避免使用多重条件判断

如果没有策略模式,当一个策略家族有5个策略算法,一会要使用A策略,一会要使用B策略,这该怎么办?使用多重的条件语句,这个方案是可行,但是不易扩展和维护,而且出现错误的概率很大,当使用了策略模式之后,可以由其他模块决定采用何种策略,策略家族对外提供访问接口即可,这样简化了操作,同时避免了大量条件语句的判断。

3、扩展性好

因为在现有的系统中增加一个策略非常容易,只要实现接口就可以了,其他的都不需要修改。

4、策略模式简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

缺点

1、策略类的数量会越来越庞大

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

2、所有的策略类都需要对外暴露

上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的。因为对于外界而言,我只想使用一个策略,干嘛要了解这个策略?那么封装类的意义在哪?这是策略模式的一个缺点。

注意

1、如果系统中的一个策略家族的具体策略数量超过了4个,那么需要考虑使用混合模式,解决策略类膨胀和对外暴露的问题,否则日后的系统维护就麻烦了。

2、策略模式跟代理模式(delegation pattern)有点相似,两者都需要依靠协议而不是具体的对象,区别在于策略模式需要一系列的对象,而代理是使用单一对象。

上一篇下一篇

猜你喜欢

热点阅读