iOS - 策略模式(Strategy Pattern)

策略模式定义

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替代。


策略模式的三个角色

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

Context封装角色

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

Strategy抽象策略角色

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

ConcreteStrategy具体策略角色

实现抽象策略中的操作,即具体实现接口,该类含有具体的算法。


辅助理解图表




如何使用策略模式

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

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、扩展性好

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


缺点

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

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

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

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


注意

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

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


参考

《设计模式之禅》


猜你喜欢

转载自blog.csdn.net/longshihua/article/details/80896810