首页 > 代码库 > 策略模式——HeadFirst 设计模式学习笔记

策略模式——HeadFirst 设计模式学习笔记

策略模式:策略模式定义了算法族,分别封装起来,让他们可以相互替换,此模式让算法的变化独立于使用算法的客户。

 

设计原则:

  • 找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。以便以后轻松的更改或扩充此部分,而不影响不需要变化的其他部分
  • 针对接口编程而不是针对实现编程。实际的实现不会被绑定,调用时只知道调用的接口,而无需知道具体的实现方式
  • 多用组合,少用继承。使用组合有很大的弹性,可以在运行时动态改变行为

要点:

  • 良好的OO设计必须遵循可复用,可拓展,可维护
  • 大部分模式允许系统的局部改变独立于其他部分
  • 把系统中会变化的部分抽出来进行封装

举例:

  1. 基础的鸭子类有方法quack,swim,display,fly等方法,使用抽象基类表示,不同种类的鸭子继承至该基类。技术分享
  2. 但是quack与fly方法对于不同的鸭子有不同的实现,无法将基类中的实现用于所有子类,并且子类具体行为表示不明确

  3. 继承不可行,使用借口呢,使用flyable,quackable借口实现
    1. 技术分享
  4. 代码无法复用,对于每类鸭子都需要实现quack和fly,造成大量的重复代码,并且当一种飞行方式改变时,该飞行方式的所有鸭子类都需要修改
  5. 将变化的行为从鸭子类中取出来。在Duck基类中添加两个实例变量,flyBehavior和quackBehavior接口类型,行为中的不同内容实现相同接口,针对接口编程,而不是针对实现编程,需要修改干个功能点使用接口,实现方式灵活多变。  
    1. 技术分享

       

    2. 技术分享

       

    3. 技术分享

核心思想:将is-a 转换为has-a.

基本的思路:将一些原先要继承的方法,以接口的方式抽象出来,然后再以实现该接口的方式定义一些类以完成实际能力的实现;同时在基类中以组合的方式将该接口的实例放入基类,基类同时提供设置这个实例的接口以及这个方法的封装,子类继承基类是对这些接口实例进行设置即可。

代码实现:

技术分享
public interface FlyBehavior {  
    public void fly();  
}  
//
public class FlyWithWings implements FlyBehavior{  
    public void fly() {  
        System.out.println("正在用翅膀飞行");  
    }  
}  
//  不飞 
public class FlyNoWay implements FlyBehavior{  
    public void fly() {  
        System.out.println("不会飞");  
    }  
}  
FlyBehavior
技术分享
 1 public interface QuackBehavior {  
 2     public void quack();  
 3 }  
 4 // 嘎嘎叫 
 5 public class Quack implements QuackBehavior. {  
 6     public void quack() {  
 7         System.out.println("嘎嘎叫");  
 8     }  
 9 }  
10 //  吱吱叫 
11 public class Squeak implements QuackBehavior{  
12     public void quack() {  
13         System.out.println("吱吱叫");  
14     }  
15 }  
16 //  不叫 
17 public class MuteQuack implements QuackBehavior{  
18     public void quack() {  
19         System.out.println("不会叫");  
20     }  
21 } 
QuackBehavior
技术分享
 1 public abstract class Duck {  
 2 //  默认的行为 
 3     FlyBehavior flyBehavior;  
 4     QuackBehavior quackBehavior;  
 5 
 6 public Duck() {  
 7     }  
 8 public void setFlyBehavior(FlyBehavior fb) {  
 9         flyBehavior = fb;  
10     }  
11 public void setQuackBehavior(QuackBehavior qb) {  
12         quackBehavior = qb;  
13     }  
14 abstract void display();  
15 public void performFly() {  
16         flyBehavior.fly();  
17     }  
18 public void performQuack() {  
19         quackBehavior.quack();  
20     }  
21 public void swim() {  
22         System.out.println("正在游泳~~");  
23     }  
24 }  
Duck
技术分享
 1 //  野鸭  
 2      public class MallardDuck extends Duck {  
 3      public MallardDuck() {  
 4          quackBehavior = new Quack();  
 5                  flyBehavior = new FlyWithWings();  //这里也可以使用setFlyBehavior方法,下同!
 6      }  
 7      public void display() {  
 8          System.out.println("绿头鸭");  
 9      }  
10 }  
11      //  红头鸭  
12      public class RedHeadDuck extends Duck {  
13      public RedHeadDuck() {  
14          flyBehavior = new FlyWithWings();  
15          quackBehavior = new Quack();  
16      }  
17      public void display() {  
18          System.out.println("红头鸭");  
19      }  
20 }  
21      //  橡皮鸭  
22     public class RubberDuck extends Duck {  
23      public RubberDuck() {  
24          flyBehavior = new FlyNoWay();  
25          quackBehavior = new Squeak();  
26      }  
27      public void display() {  
28          System.out.println("橡皮鸭");  
29      }  
30 }  
Different kinds of Duck
技术分享
 1 public class MiniDuckSimulator {  
 2 
 3 public static void main(String[] args) {  
 4 
 5         MallardDuck    mallard = new MallardDuck();  
 6         RubberDuck    rubberDuckie = new RubberDuck();  
 7         RedHeadDuck    redHeadDuck = new RedHeadDuck();  
 8 
 9         mallard.performQuack();  
10         rubberDuckie.performQuack();  
11         redHeadDuck.performQuack();  
12     }  
13 } 
TestDuck

 

策略模式——HeadFirst 设计模式学习笔记