对于同一业务逻辑, 在不同对象中有不同的细节实现, 但逻辑(算法)框架是相同的。例如对文本的对齐方式可以有“左对齐”、“居中”......实现在文本类中不合适(因为还有其他的格式化方式),可以把它们封装成统一的接口。
定义一系列的算法,把它们逐一封装起来,并使它们可以相互替换。 [1]内部状态改变时改变它的行为。
- 根据内部状态调整策略
-
只将接口封装仍需要进行策略的选择,在添加新算法时会违反开放封闭的原则。
-
用组合+委托(或直接用“依赖注入”) —— 创建上下文Context —— 客户只和Context交互,Strategy从Context中获取参数 / 让Strategy在需要的时候回调Context对象
要素
策略类主要是封装,重难点在Context类(与Strategy的交互) —— 组合 + “委托”
- 维护一个Strategy对象的引用
- 实现配置ConcreteStrategy
- 将客户的参数传递给Strategy(定义一个接口让Strategy访问它的数据)
客户需要创建ConcreteStrategy对象
- 用组合替代继承
- 相关算法系列统一封装
- 用“依赖注入” 或 委托 消除条件语句(条件被移入了Strategy中)
- 为同一行为提供不同的实现
-
用户需要了解所有ConcreteStrategy
-
Strategy与Context之间的通信开销
- 该问题来源于ConcreteStrategy都继承与同一接口,但根据内部实现的不同,可能用不到全部参数。也就是说Context传递给ConcreteStrategy的参数可能需要更紧密的耦合。
-
如果Strategy需要应用对象,将会增加对象的数量。
- 处理方案是:将Strategy实现为可供Context共享的无状态对象,而其余的状态都由Context维护 ==> 享元模式
- 行为一致,为了不同需求(例如时间、空间......)需要不同的实现供选择
- 许多相关的类仅行为有异(内部参数/状态相同),进行封装,可以用其中一个行为来配置类
- 有很多switch-case时