Skip to content

Latest commit

 

History

History
49 lines (33 loc) · 2.15 KB

File metadata and controls

49 lines (33 loc) · 2.15 KB

策略模式 Strategy

背景

对于同一业务逻辑, 在不同对象中有不同的细节实现, 但逻辑(算法)框架是相同的。例如对文本的对齐方式可以有“左对齐”、“居中”......实现在文本类中不合适(因为还有其他的格式化方式),可以把它们封装成统一的接口。

定义

定义一系列的算法,把它们逐一封装起来,并使它们可以相互替换。 [1]内部状态改变时改变它的行为

难点 & 关键

  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时