ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
18.2 策略模式的定义 策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(Policy Pattern)。其定义如下: Define a family of algorithms,encapsulate each one,and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。) 这个定义是非常明确、清晰的,“定义一组算法”,看看我们的三个计谋是不是三个算法?“将每个算法都封装起来”,封装类Context不就是这个作用吗?“使它们可以互换”当然可以互换了,都实现是相同的接口,那当然可以相互转化了。我们看看策略模式的通用类图,如图18-3所示。 ![](https://box.kancloud.cn/2016-08-14_57b00365cb142.jpg) 图18-3 策略模式通用类图 策略模式使用的就是面向对象的继承和多态机制,非常容易理解和掌握,我们再来看看策略模式的三个角色: ● Context封装角色 它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。 ● Strategy抽象策略角色 策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。各位看官可能要问了,类图中的AlgorithmInterface是什么意思,嘿嘿,algorithm是“运算法则”的意思,结合起来意思就明白了吧。 ● ConcreteStrategy具体策略角色 实现抽象策略中的操作,该类含有具体的算法。 我们再来看策略模式的通用源码,非常简单。先看抽象策略角色,它是一个非常普通的接口,在我们的项目中就是一个普通得不能再普通的接口了,定义一个或多个具体的算法,如代码清单18-7所示。 代码清单18-7 抽象的策略角色 public interface Strategy {      //策略模式的运算法则      public void doSomething(); } 具体策略也是非常普通的一个实现类,只要实现接口中的方法就可以,如代码清单18-8所示。 代码清单18-8 具体策略角色 public class ConcreteStrategy1 implements Strategy {      public void doSomething() {              System.out.println("具体策略1的运算法则");      } } public class ConcreteStrategy2 implements Strategy {      public void doSomething() {              System.out.println("具体策略2的运算法则");      } } 策略模式的重点就是封装角色,它是借用了代理模式的思路,大家可以想想,它和代理模式有什么差别,差别就是策略模式的封装角色和被封装的策略类不用是同一个接口,如果是同一个接口那就成为了代理模式。我们来看封装角色,如代码清单18-9所示。 代码清单18-9 封装角色 public class Context {      //抽象策略      private Strategy strategy = null;        //构造函数设置具体策略      public Context(Strategy _strategy){              this.strategy = _strategy;      }      //封装后的策略方法      public void doAnythinig(){              this.strategy.doSomething();      } } 高层模块的调用非常简单,知道要用哪个策略,产生出它的对象,然后放到封装角色中就完成任务了,如代码清单18-10所示。 代码清单18-10 高层模块 public class Client {      public static void main(String[] args) {              //声明一个具体的策略              Strategy strategy = new ConcreteStrategy1();              //声明上下文对象              Context context = new Context(strategy);              //执行封装后的方法              context.doAnythinig();      } } 策略模式就是这么简单,偷着乐吧,它就是采用了面向对象的继承和多态机制,其他没什么玄机。想想看,你真实的业务环境有这么简单吗?一个类实现多个接口很正常,你要有火眼金睛看清楚哪个接口是抽象策略接口,哪些是和策略模式没有任何关系,这就是你作为系统分析师的价值所在。