ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
第18章 策略模式 18.1 刘备江东娶妻,赵云他容易吗 在三国演义中,我最佩服诸葛亮的地方不是因为他未出茅庐而有三分天下的预测,也不是他在赤壁鏖战中借东风的法术,更不是他七擒七纵孟获的策略。那是什么呢?是他“气死周瑜,骂死王朗”的气度和风范!想想看,你用“气”能把一个轮胎打爆,用“气”枪能够把路灯打碎,但是要把跟你没有任何血缘关系的人气死有多困难呀,更何况是周瑜这种智慧型人物! 在诸葛亮气周瑜的过程中,有一件事情:那就是周瑜赔了夫人又折兵这件事情。事情经过是这样的:孙权看刘备有雄起之意,杀是不能杀了,那会惹天下人唾弃,就想个招儿挫他一下,那有什么办法呢?孙权有个妹妹——孙尚香,准备招刘备做女婿,然后孙权想办法把刘备软禁起来,孙权的想法还是很单纯的嘛,就是不让你刘备回西川,然后我东吴想干啥就干啥,夺荆州,吞西川也不是不可能的。东吴的想法是好的,无奈中间多了智谋无敌的诸葛亮,他早就预测了东吴有此招数,于是在刘备去东吴招亲之前,特授以伴郎赵云三个锦囊,说是按天机拆开解决棘手问题。 这三个妙计分别是:找乔国老帮忙(也就是走后门了),求吴国太放行(诉苦)以及孙夫人断后,对这三个妙计不熟悉的读者可以去温习一下《三国演义》,这里就不多说了。想想看,这三个计谋有什么相似之处,他们都是告诉赵云要怎么执行,也就是说这三个计谋都有一个方法是执行,具体执行什么内容,每个计谋当然不同了,分析到这里,我们是不是就有这样一个设计思路:三个妙计应该实现的是同一个接口?聪明!是的,我们来看类图,如图18-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b003659c5e4.jpg) 图18-1 三个策略类图 这是非常简单的类图,在这个场景中的三个主要角色都已经有了,每个妙计都提供了一个可执行的方法,我们先来看接口,如代码清单18-1所示。 代码清单18-1 妙计接口 public interface IStrategy {      //每个锦囊妙计都是一个可执行的算法      public void operate(); } 接口很简单,定义了一个方法operate,每个妙计都是可执行的,否则那叫什么妙计,我们先看第一个妙计——找乔国老开后门,如代码清单18-2所示。 代码清单18-2 乔国老开后门 public class BackDoor implements IStrategy {      public void operate() {              System.out.println("找乔国老帮忙,让吴国太给孙权施加压力");      } } 第二个妙计是找吴国太哭诉,企图给自己开绿灯,如代码清单18-3所示。 代码清单18-3 吴国太开绿灯 public class GivenGreenLight implements IStrategy {      public void operate() {              System.out.println("求吴国太开绿灯,放行!");      } } 第三个妙计是在逃跑的时候,让新娘子孙夫人断后,谁来砍谁,这是非常好的主意,如代码清单18-4所示。 代码清单18-4 孙夫人断后 public class BlockEnemy implements IStrategy {      public void operate() {              System.out.println("孙夫人断后,挡住追兵");      } } 在这个场景中,三个妙计都有了,那还缺少两个配角:第一,妙计肯定要放到一个地方吧,这么重要的东西要保管呀,也就是承装妙计的锦囊,所以俗称锦囊妙计嘛;第二,这些妙计都要有一个执行人吧,是谁?当然是赵云了,妙计是小亮给的,执行者是赵云。赵云就是一个干活的人,从锦囊中取出妙计,执行,然后获胜。过程非常清晰,我们把完整的过程设计出来,如图18-2所示。 在类图中增加了一个Context封装类(也就是锦囊),其作用是承装三个策略,方便赵云使用,我们来看Context代码,如代码清单18-5所示。 ![](https://box.kancloud.cn/2016-08-14_57b00365b2bbb.jpg) 图18-2 完整类图 代码清单18-5 锦囊 public class Context {      //构造函数,你要使用哪个妙计      private IStrategy straegy;      public Context(IStrategy strategy){              this.straegy = strategy;      }      //使用计谋了,看我出招了      public void operate(){              this.straegy.operate();      } } 通过构造函数把策略传递进来,然后用operate()方法来执行相关的策略方法。三个妙计有了,锦囊也有了,然后就是赵云雄赳赳地揣着三个锦囊,拉着已步入老年行列的、还想着娶纯情少女的刘老爷子去入赘了。嗨,还别说,小亮同志的三个妙计还真是不错,如代码清单18-6所示。 代码清单18-6 使用计谋 public class ZhaoYun {      //赵云出场了,他根据诸葛亮给他的交代,依次拆开妙计      public static void main(String[] args) {              Context context;              //刚刚到吴国的时候拆第一个              System.out.println("---刚刚到吴国的时候拆第一个---");              context = new Context(new BackDoor()); //拿到妙计              context.operate();  //拆开执行              System.out.println("\n\n\n\n\n\n\n\n");              //刘备乐不思蜀了,拆第二个了              System.out.println("---刘备乐不思蜀了,拆第二个了---");              context = new Context(new GivenGreenLight());              context.operate();  //执行了第二个锦囊              System.out.println("\n\n\n\n\n\n\n\n");              //孙权的小兵追来了,咋办?拆第三个              System.out.println("---孙权的小兵追来了,咋办?拆第三个---");              context = new Context(new BlockEnemy());              context.operate();  //孙夫人退兵              System.out.println("\n\n\n\n\n\n\n\n");      } } 我们来看看这段故事,运行结果如下: ---刚刚到吴国的时候拆第一个--- 找乔国老帮忙,让吴国太给孙权施加压力 ---刘备乐不思蜀了,拆第二个--- 求吴国太开个绿灯,放行! ---孙权的小兵追来了,咋办?拆第三个--- 孙夫人断后,挡住追兵 恩,不错,就这三招,搞得孙权是“赔了夫人又折兵”。那我们描述这个故事的过程就是策略模式。