设计模式--策略模式

策略模式

  定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。(虽然能理解意思,但真心记不住= =)

 

  策略模式其实不难,顾名思义就是更改策略(策略接口下的子类)。首先是需要一个策略接口:Strategy,可以有n个子类实现此接口;其次是

拥有此接口对象(注意是接口对象,而不是任意的子类)的客户端,那么客户端可以在运行时根据需要选择策略(子类)。

  这样做的好处:

    1. 维护方便:若策略经常改变,则更换策略便是;若出现新策略,那么实现一个继承策略接口的子类便可。其实这都可以归结为针对接口编程带来的好处。

    2. 强大的组合:想象一下,若有n个策略接口,每个策略接口都有m个子类。客户端只要维护n个策略接口对象,在运行时更改具体子类,那么其组合效应             是非常惊人的,可以很方便的根据实际需要组装出各种接口组合。

  

  说了这么多,写一个例子:

  有这样一个场景:有3种鸭子(为毛是鸭子呢- -):小鸭、会飞的老鸭(这个更囧吧)、玩具鸭。它们具有两类行为:叫和飞。具体行为分配如下列表:

      quack   fly
   小鸭:  不会叫    不会飞
   老鸭:    嘎嘎叫      会飞
   橡皮鸭: 吱吱叫    不会飞

  一种常见的做法是:写一个Duck的抽象类,包括quack()和fly()方法(应当是抽象的,因为每种鸭子的行为不同),然后这三种鸭子继承Duck抽象类。这样做的问题:1. 代码无法复用。当两种鸭子的某一行为相同时,你只能去copy代码;当增加一种新鸭子时,也只能重写其行为。 2. 当鸭子的行为改变时,很显然只能修改源代码!这样不好嘛?好是好,可有没有想过运行时修改,而不用修改源代码呢!

  现在就用策略模式来改变这一现状吧:)

  1. FlyBehaviour接口及其两个子类CanFly和CantFly,分别代表“会飞”和“不会飞”。

View Code
 1 package StrategyPattern;
 2 /*
 3  * 飞行接口
 4  */
 5 public interface FlyBehaviour {
 6     public void fly();
 7 }
 8 
 9 
10 
11 package StrategyPattern;
12 
13 public class CanFly implements FlyBehaviour {
14 
15     @Override
16     public void fly() {
17         // TODO Auto-generated method stub
18         System.out.print("会飞");
19     }
20 
21 }
22 
23 
24 
25 package StrategyPattern;
26 
27 public class CantFly implements FlyBehaviour {
28 
29     @Override
30     public void fly() {
31         // TODO Auto-generated method stub
32         System.out.print("不会飞");
33     }
34 
35 }

 

  2. QuackBehaviour接口及其三个子类NoQuack,GagaQuack和ZhizhiQuack,分别代表“不会叫”、“嘎嘎叫”、“吱吱叫”。

View Code
 1 package StrategyPattern;
 2 /**
 3  * 叫行为。
 4  * @author Administrator
 5  *
 6  */
 7 public interface QuackBehaviour {
 8     public void quack();
 9 }
10 
11 
12 package StrategyPattern;
13 
14 public class NoQuack implements QuackBehaviour {
15 
16     @Override
17     public void quack() {
18         // TODO Auto-generated method stub
19         System.out.print("不会叫");
20     }
21 
22 }
23 
24 package StrategyPattern;
25 
26 public class GagaQuack implements QuackBehaviour {
27 
28     @Override
29     public void quack() {
30         // TODO Auto-generated method stub
31         System.out.print("嘎嘎叫");
32     }
33 
34 }
35 
36 
37 package StrategyPattern;
38 
39 public class ZhizhiQuack implements QuackBehaviour {
40 
41     @Override
42     public void quack() {
43         // TODO Auto-generated method stub
44         System.out.print("吱吱叫");
45     }
46 
47 }

 

  3. Duck抽象类,含有FlyBehaviour和QuackBehaviour的两个接口对象。及其三个子类,LittleDuck、OldDuck和RubbDuck。

View Code
  1 package StrategyPattern;
  2 
  3 import java.awt.DisplayMode;
  4 
  5 /**
  6  * duck的抽象父类。
  7  * @author Administrator
  8  *
  9  */
 10 public abstract class Duck {
 11     
 12     FlyBehaviour flyBh;
 13     QuackBehaviour quackBh;
 14     
 15     public Duck(FlyBehaviour fly, QuackBehaviour quack) {
 16         this.flyBh = fly;
 17         this.quackBh = quack;
 18     }
 19     
 20     public void setFlyBehaviour(FlyBehaviour fly) {
 21         this.flyBh = fly;
 22     }
 23     
 24     public void setQuackBehaviour(QuackBehaviour quack) {
 25         this.quackBh = quack;
 26     }
 27     
 28     public void performFly() {
 29         flyBh.fly();
 30     }
 31     
 32     public void peformQuack() {
 33         quackBh.quack();
 34     }
 35     
 36     public abstract void display();
 37     
 38 }
 39 
 40 
 41 
 42 package StrategyPattern;
 43 
 44 public class LittleDuck extends Duck {
 45 
 46     public LittleDuck(FlyBehaviour fly, QuackBehaviour quack) {
 47         super(fly, quack);
 48         // TODO Auto-generated constructor stub
 49     }
 50 
 51     @Override
 52     public void display() {
 53         // TODO Auto-generated method stub
 54         System.out.println();
 55         System.out.print("小鸭");
 56         peformQuack();
 57         performFly();
 58     }
 59 
 60 }
 61 
 62 
 63 
 64 package StrategyPattern;
 65 
 66 public class OldDuck extends Duck {
 67 
 68     public OldDuck(FlyBehaviour fly, QuackBehaviour quack) {
 69         super(fly, quack);
 70         // TODO Auto-generated constructor stub
 71     }
 72 
 73     @Override
 74     public void display() {
 75         // TODO Auto-generated method stub
 76         System.out.println();
 77         System.out.print("老鸭");
 78         peformQuack();
 79         performFly();
 80     }
 81 
 82 }
 83 
 84 
 85 
 86 
 87 package StrategyPattern;
 88 
 89 public class RubbDuck extends Duck {
 90 
 91     public RubbDuck(FlyBehaviour fly, QuackBehaviour quack) {
 92         super(fly, quack);
 93         // TODO Auto-generated constructor stub
 94     }
 95 
 96     @Override
 97     public void display() {
 98         // TODO Auto-generated method stub
 99         System.out.println();
100         System.out.print("橡皮鸭");
101         peformQuack();
102         performFly();
103     }
104 
105 }

 

  最后,看看效果吧:

View Code
1     public static void main(String[] args) {
2         // TODO Auto-generated method stub
3         Duck littleDuck = new LittleDuck(new CantFly(), new NoQuack());
4         Duck oldDuck = new OldDuck(new CanFly(), new GagaQuack());
5         Duck rubbDuck = new RubbDuck(new CantFly(), new ZhizhiQuack());
6         littleDuck.display();
7         oldDuck.display();
8         rubbDuck.display();
9     }

运行结果:

小鸭不会叫不会飞
老鸭嘎嘎叫会飞
橡皮鸭吱吱叫不会飞

 

 

  

posted @ 2012-10-23 14:27  Alex_Monkey  阅读(188)  评论(0编辑  收藏  举报