策略模式

 定义

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。

 

策略模式用来解耦策略的定义、创建、使用。实际上,一个完整的策略模式就是由这三个部分组成的

  • 策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。
  • 策略的创建由工厂类来完成,封装策略创建的细节。
  • 策略模式包含一组策略可选,客户端代码如何选择使用哪个策略,有两种确定方法:编译时静态确定和运行时动态确定。其中,“运行时动态确定”才是策略模式最典型的应用场景。
除此之外,我们还可以通过策略模式来移除 if-else 分支判断。实际上,这得益于策略工厂类,更本质上点讲,是借助“查表法”,根据 type 查表替代根据 type 分支判断。
问题
当我们添加新的排序算法的时候,还是需要修改代码,并不完全符合开闭原则。有什么办法让我们完全满足开闭原则呢?
通过一个配置文件,策略工厂类读取配置文件,通过反射了动态地加载这些策略类、创建策略对象。新添加一个策略的时候,只需要将这个新添加的策略类添加到配置文件
总结
如果 if-else 分支判断不复杂、代码不多,这并没有任何问题,毕竟 if-else 分支判断几乎是所有编程语言都会提供的语法,存在即有理由。遵循 KISS 原则,怎么简单怎么来,就是最好的设计。非得用策略模式,搞出 n 多类,反倒是一种过度设计。
一提到策略模式,有人就觉得,它的作用是避免 if-else 分支判断逻辑。实际上,这种认识是很片面的。
策略模式主要的作用还是解耦策略的定义、创建和使用,控制代码的复杂度,让每个部分都不至于过于复杂、代码量过多。除此之外,对于复杂代码来说,策略模式还能让其满足开闭原则,添加新策略的时候,最小化、集中化代码改动,减少引入 bug 的风险

UML类图

优点 

  1. 提供“开闭原则”的完美支持,不修改原有系统的基础上选择算法或行为,也可灵活增加新算法
  2. 提供了管理相关算法族的方法 (很好得管理算法族,提高复用性)
  3. 提供了可以替换继承关系的办法 
  4. 可以避免使用多重条件转移语句

缺点

  1. 客户端必须知道所有具体策略类,并自行决定使用哪一个
  2. 产生很多策略类,可以通过享元模式一定程度上减少对象的数量

适用环境

  1. 系统中有许多类,他们的区别仅在于他们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种
  2. 一个系统需要动态在几种算法中选择一种
  3. 如果一个算法有很多行为,如果不用恰当的模式,这些算法只好用多重条件选择语句来实现。
  4. 不希望客户端知道复杂的、与算法相关的数据结构,再具体的策略类中封装算法的相关数据结构,提高算法的保密与安全性

 

refer

posted @ 2020-03-15 22:08  vvf  阅读(126)  评论(0编辑  收藏  举报