设计模式 -- 策略模式

Head First 里面对策略模式的描述:
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
 
例子:
我们要制作一堆游戏里面的猫猫形象,里面的猫暂时主要
有2个技能:跑与叫,但不是每一只猫的这两种技能都是好的,有的不会,有的差,有的好;
共同技能:游泳;
当然它们各自有自己的形态;
 
于是乎有了以下的类图:
策略模式
代码实现如下:
RunBehaviour 抽象出跑的行为接口
1 package strategy.run;
2 
3 /**
4  * Created by chenjiayin on 2017/3/17.
5  */
6 public interface RunBehaviour
7 {
8     void run();
9 }

 

NoRunBehaviour 是 RunBehaviour  的算法族里面的一员
 1 package strategy.run;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class NoRunBehaviour implements RunBehaviour
 7 {
 8     @Override
 9     public void run()
10     {
11         System.out.println("~~~ no run ~~~");
12     }
13 }

 

BadRunBehaviour 也是 RunBehaviour  的算法族里面的一员

 1 package strategy.run;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class BadRunBehaviour implements RunBehaviour
 7 {
 8     @Override
 9     public void run()
10     {
11         System.out.println("~~~ bad run ~~~");
12     }
13 }


GoodRunBehaviour 也是 RunBehaviour  的算法族里面的一员

 1 package strategy.run;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class GoodRunBehaviour implements RunBehaviour
 7 {
 8     @Override
 9     public void run()
10     {
11         System.out.println("~~~ good run ~~~");
12     }
13 }

 

好了,上面完成了run的算法族,就该轮到meow了,同样的道理,抽象出meow 接口

1 package strategy.meow;
2 
3 /**
4  * Created by chenjiayin on 2017/3/17.
5  */
6 public interface MeowBehaviour
7 {
8     void meow();
9 }


NoMeowBehaviour

 1 package strategy.meow;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class NoMeowBehaviour implements MeowBehaviour
 7 {
 8     @Override
 9     public void meow()
10     {
11         System.out.println("~~~ no meow ~~~");
12     }
13 }

 

BadMeowBehaviour

 1 package strategy.meow;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class BadMeowBehaviour implements MeowBehaviour
 7 {
 8     @Override
 9     public void meow()
10     {
11         System.out.println("~~~ bad meow ~~~");
12     }
13 }

 

GoodMeowBehaviour

 1 package strategy.meow;
 2 
 3 /**
 4  * Created by chenjiayin on 2017/3/17.
 5  */
 6 public class GoodMeowBehaviour implements MeowBehaviour
 7 {
 8     @Override
 9     public void meow()
10     {
11         System.out.println("~~~ good meow ~~~");
12     }
13 }

 

到此阶段,算法族已经封装完毕,是时候来使用它们了。抽象出Cat 的抽象类

 1 package strategy.cat;
 2 
 3 import strategy.run.RunBehaviour;
 4 import strategy.meow.MeowBehaviour;
 5 
 6 /**
 7  * Created by chenjiayin on 2017/3/17.
 8  */
 9 public abstract class AbstractCat
10 {
11     RunBehaviour runBehaviour;
12     MeowBehaviour meowBehaviour;
13 
14     public void fly()
15     {
16         runBehaviour.run();
17     }
18 
19     public void quack()
20     {
21         meowBehaviour.meow();
22     }
23 
24     public void swim()
25     {
26         System.out.println("~~~ swim ~~~");
27     }
28 
29     public abstract void diplay();
30 }

 

肥猫(FatCat),由于太胖了,不会跑,只会叫

 1 package strategy.cat;
 2 
 3 import strategy.run.NoRunBehaviour;
 4 import strategy.meow.GoodMeowBehaviour;
 5 
 6 /**
 7  * Created by chenjiayin on 2017/3/17.
 8  */
 9 public class FatCat extends AbstractCat
10 {
11     public FatCat()
12     {
13         runBehaviour = new NoRunBehaviour();
14         meowBehaviour = new GoodMeowBehaviour();
15     }
16 
17     @Override
18     public void diplay()
19     {
20         System.out.println("*** fat cat ***");
21     }
22 }

 

瘦猫(ThinCat)

 1 package strategy.cat;
 2 
 3 import strategy.run.GoodRunBehaviour;
 4 import strategy.meow.BadMeowBehaviour;
 5 
 6 /**
 7  * Created by chenjiayin on 2017/3/17.
 8  */
 9 public class ThinCat extends AbstractCat
10 {
11     public ThinCat()
12     {
13         runBehaviour = new GoodRunBehaviour();
14         meowBehaviour = new BadMeowBehaviour();
15     }
16 
17     @Override
18     public void diplay()
19     {
20         System.out.println("*** thin cat ***");
21     }
22 }

 

最后,我们来使用下面的方法来验证一下我们的代码!

 1 package strategy;
 2 
 3 import strategy.cat.AbstractCat;
 4 import strategy.cat.FatCat;
 5 import strategy.cat.ThinCat;
 6 
 7 /**
 8  * Created by chenjiayin on 2017/3/17.
 9  */
10 public class StrategyMain
11 {
12     public static void main(String[] args)
13     {
14         AbstractCat fatDuck = new FatCat();
15         AbstractCat thinDuck = new ThinCat();
16 
17         fatDuck.diplay();
18         fatDuck.quack();
19         fatDuck.fly();
20         fatDuck.swim();
21 
22         System.out.println();
23 
24         thinDuck.diplay();
25         thinDuck.quack();
26         thinDuck.fly();
27         thinDuck.swim();
28     }
29 }


输出:
*** fat cat ***
~~~ good meow ~~~
~~~ no run ~~~
~~~ swim ~~~

*** thin cat ***
~~~ bad meow ~~~
~~~ good run ~~~
~~~ swim ~~~

 

 
总结:
其实策略模式就有点类似于做象限轴。
上面的例子当中就是一个二维的象限轴,RunBehaviour 就是X轴,MeowBehaviour 就是Y轴,而FatCat 与ThinCat 就是一个具体在二维空间上的描点。
所以,随着象限轴的增加,可组合而成的点(具体的类)也会越来越多,但是我们只需要很少量的改动,就可以为我们带来大量的扩展。
posted @ 2017-03-19 23:48  Artemis29  阅读(202)  评论(2编辑  收藏  举报