大话设计模式-策略模式
工厂在业务逻辑增加的过程中,也会越来越复杂,维护性逐渐降低。
策略模式
定义了算法家族,分别封装起来,让其可以互相替换。此模式让算法的变化不影响使用算法的客户。
核心在于算法是随时都可能相互替换的。
Strategy
类,定义所有支持的算法的公共接口ConcreteStrategy
类,封装具体算法或行为,继承自Strategy
Context
类,使用一个ConcreteStrategy
进行配置,维护一个对Strategy
对象的引用
1 | class Context |
但在具体实现过程中,仍然不能完全将策略选择过程从客户端中剥离。可以考虑与简单工厂模式结合。
1 | class CashContext: |
其与简单工厂的不同在于降低了客户端的使用门槛:
1 | # 简单工厂需要认识两个类:`CashSuper`和`CashFactory` |
策略模式本质上是定义一系列算法的方法,它们完成相同的工作,只是实现不同,我们可以用相同的方式调用所有的算法,从而降低算法类与使用算法类之间的耦合。
Strategy
类层次为Context
定义了一系列可供重用的算法或行为,继承有助于析出这些算法的公共功能。例如本例中的get_result
此外还简化了单元测试,因为每个算法都有自己的类,可通过自己的接口单独测试。每个算法课保证它没有错误,修改其中一个也不影响其他算法。
策略模式封装了变化,从而在客户端中消除大量条件语句:将特殊行为封装进独立的Strategy
类。
实践中,策略模式可以用来几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
此外,策略模式本身而言,选用具体实现的职责由客户端对象承担,并转给
Context
对象,本身并不解除客户端选择判断的压力,而与工厂模式结合后,选择策略的职责由Context
承担,最大化减轻客户端职责。
使用反射技术则可以在Context
类中避免对switch
语句的反复修改。
感想
策略模式似乎对简单工厂模式又做了一层抽象/隔离,避免用户直接接触到工厂类,同时提供了一个统一的接口。
Refector GURU
策略模式要求把做同样的事的不同方法分别抽象成不同的类,这些类称为 策略。上下文对象可以存储一个策略,并把任务交给策略执行。上下文对象并不知道该如何选择策略,client通过上下文来选择合适的策略。
1 | class Strategy { |