策略模式


目录(?) [+]
  1. 设计模式学习--策略模式Strategy Pattern
    1. 什么是策略模式
    2. 怎么使用策略模式设计程序
    3. 三个设计原则
    4. 策略模式应用例子
    5. 在没有使用策略模式之前可能这样
    6. 使用策略模式会是这样

设计模式学习--策略模式(Strategy Pattern)

什么是策略模式?

定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立使用算法的客户。

怎么使用策略模式设计程序?

分开变化和不会变化的部分,建立一组新的类来代表变化的部分。

三个设计原则:

1. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2. 针对接口编程,而不是针对实现编程。
3. 多用组合,少用继承。

策略模式应用例子:

一只鸭Duck,可能是以下几种不同类型的鸭
(MallardDuck) 绿头鸭--会飞会呱呱叫
(RedHeadDuck) 红头鸭--会飞会呱呱叫
(RubberDuck) 橡皮鸭--不会飞会叽叽叫
(DecoyDuck) 诱饵鸭--不会飞也不会叫
(ModelDuck) 模型鸭--不会飞也不会叫


在没有使用策略模式之前可能这样:


1. 利用继承来提供Duck的行为
===》导致代码在多个子类中重复
===》运行时的行为不容易改变
===》很难知道所有鸭子的全部行为
===》改变会牵一发动全身,造成其他鸭子不想要的改变。
2. 把会变的行为提取出来设计成一个接口
===》导致重复代码变多
===》导致代码无法进行复用



使用策略模式会是这样:

1. 采用良好的oo软件设计原则
2. 分开变化和不会变化的部分
3.  针对接口编程


具体实现:
所有类型鸭的抽象:Duck类
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. /** 
  4.  * 所有类型鸭子的超类 
  5.  * @author wwj 
  6.  * 
  7.  */  
  8. public abstract class Duck {  
  9.     FlyBehavior flyBehavior;        //飞行行为  
  10.     QuackBehavior quackBehavior;    //呱呱叫行为  
  11.       
  12.     public void performQuack(){  
  13.         quackBehavior.quack();  
  14.     }  
  15.       
  16.     public void swim(){  
  17.         System.out.println("All ducks float, even decoys!");  
  18.     }  
  19.       
  20.     public abstract void display();  
  21.       
  22.     public void performFly() {  
  23.         flyBehavior.fly();  
  24.     }  
  25.       
  26.     public void setFlyBehavior(FlyBehavior fb) {  
  27.         flyBehavior = fb;  
  28.     }  
  29.       
  30.     public void setQuackBehavior(QuackBehavior qb) {  
  31.         quackBehavior = qb;  
  32.     }  
  33.       
  34. }  


把会变化的部分取出并“封装”起来,好让其他部分不会受到影响
提供两个接口FlyBehavior和QuackBehavior
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public interface FlyBehavior {  
  4.     public void fly();  
  5. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public interface QuackBehavior {  
  4.     public void quack();  
  5. }  

实现鸭子的行为(飞行类)
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class FlyWithWings implements FlyBehavior {  
  4.   
  5.     @Override  
  6.     public void fly() {  
  7.         //实现鸭子飞行  
  8.         System.out.println("I'm flying!");  
  9.     }  
  10.   
  11. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class FlyNoWay implements FlyBehavior {  
  4.   
  5.     @Override  
  6.     public void fly() {  
  7.         //什么都不做,不会飞  
  8.         System.out.println("I can't fly");  
  9.     }  
  10.   
  11. }  


[java] view plain copy print ?
  1. public class FlyRocketPowered implements FlyBehavior {  
  2.       
  3.     @Override  
  4.     public void fly() {  
  5.         System.out.println("I'm flying with a rocket!");  
  6.     }  
  7.   
  8. }  


实现鸭子的行为(呱呱叫)
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class Quack implements QuackBehavior {  
  4.   
  5.     @Override  
  6.     public void quack() {  
  7.         //实现鸭子呱呱叫  
  8.         System.out.println("Quack");  
  9.     }  
  10.   
  11. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class Squack implements QuackBehavior {  
  4.   
  5.     @Override  
  6.     public void quack() {  
  7.         //橡皮鸭子叽叽叫  
  8.         System.out.println("Squack");  
  9.     }  
  10.   
  11. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class MuteQuack implements QuackBehavior {  
  4.   
  5.     @Override  
  6.     public void quack() {  
  7.         // 什么都不做,不会叫  
  8.     }  
  9.   
  10. }  

整合鸭子的行为,让不同的鸭子继承鸭类(Duck)
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. /** 
  4.  * 绿头鸭继承鸭类 
  5.  * @author wwj 
  6.  * 
  7.  */  
  8. public class MallardDuck extends Duck{  
  9.       
  10.     /** 
  11.      * 因为MallardDuck继承Duck类,所以具有flyBehavior与quackBehavior实例变量 
  12.      */  
  13.     public MallardDuck() {  
  14.         quackBehavior = new Quack(); //真正的呱呱叫     
  15.         flyBehavior = new FlyWithWings();   //会用翅膀飞  
  16.     }  
  17.       
  18.     public void display() {  
  19.         System.out.println("I'm a real Mallard duck");  //我是一个真正的绿头鸭  
  20.     }  
  21.       
  22. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class RedheadDuck extends Duck{  
  4.     public RedheadDuck() {  
  5.         flyBehavior = new FlyWithWings();  
  6.         quackBehavior = new Quack();  
  7.     }  
  8.       
  9.     @Override  
  10.     public void display() {  
  11.         System.out.println("I'm a RedheadDuck!!");  //红头鸭  
  12.     }  
  13.   
  14. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class RubberDuck extends Duck{  
  4.     public RubberDuck() {  
  5.     }  
  6.   
  7.     @Override  
  8.     public void display() {  
  9.         System.out.println("I'm a RubberDuck!!!");  
  10.     }  
  11.   
  12. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class ModelDuck extends Duck {  
  4.     public ModelDuck() {  
  5.         flyBehavior = new FlyNoWay();   //不会飞  
  6.         quackBehavior = new Quack();    //会叽叽叫  
  7.     }  
  8.       
  9.     @Override  
  10.     public void display() {  
  11.         System.out.println("I'm a model duck");  
  12.     }  
  13.   
  14. }  

[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class DecoyDuck extends Duck{  
  4.     public DecoyDuck(){  
  5.     }  
  6.   
  7.     @Override  
  8.     public void display() {  
  9.         System.out.println("I'm a DecoyDuck!!!");   //我是一只诱饵鸭  
  10.     }  
  11.       
  12. }  

测试类:
[java] view plain copy print ?
  1. package strategyPattern;  
  2.   
  3. public class MiniDuckSimulator {  
  4.     public static void main(String[] args) {  
  5.         Duck mallard = new MallardDuck();  
  6.         mallard.performQuack();  
  7.         mallard.performFly();  
  8.           
  9.           
  10.         //动态改变模型鸭的行为--通过调用继承来的setter方法  
  11.         Duck model = new ModelDuck();  
  12.         model.performFly();  
  13.         model.setFlyBehavior(new FlyRocketPowered());   //委托  
  14.         model.performFly();  
  15.     }  
  16. }  


测试结果:
[java] view plain copy print ?
  1. Quack  
  2. I'm flying!  
  3. I can't fly  
  4. I'm flying with a rocket!  


确实,使用策略模式之后,代码变得可复用了,可以适应更多的变化,而不会互相影响。良好的oo设计必须具备可复用、可扩充、可维护三个特性。模式是前人历经验证的经验,可以用来解决程序设计当中的各种问题。




你可能感兴趣的:(策略模式)