HeadFirst设计模式——策略模式

使用模式最好的方式是:“把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们。”

书中例子:
有一套模拟鸭子的游戏。游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫。游戏采用了标准OO技术,设计了一个鸭子超类Duck,并让各种鸭子继承此超类。
现在需要为鸭子添加新的行为Fly。如果在SuperClass中添加Fly则会使所有的鸭子对象都具有该方法。但实际中有些鸭子(例如橡皮鸭)是不会飞的。这种情况下只能在橡皮鸭子类中覆盖Fly。这无疑比较丑陋。

利用继承来提供Duck的行为,这会导致下列哪些缺点?
  1. 代码在多个子类中重复
  2. 运行时行为不容易改变
  3. 很难知道所有鸭子的行为
  4. 改变会牵一发而动全身,造成其他鸭子不想要的改变
如果采用接口呢

每个会飞的子类都需要实现Fly接口,会出现大量重复代码,没有做到代码复用。

软件开发的一个不变真理:CHANGE

由于种种原因,我们所写的代码会一直根据需求变动。实际上代码维护的时间远远超过了代码开发的时间。所以在写代码时一定要让代码灵活有弹性。

设计原则:

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

根据第一条原则,我们应该将鸭子的行为从Duck中分离出来,建立一组新类来表示每个行为。
根据第二条原则,每个行为类都应该实现对应的接口
喵

实现代码:
//超类
public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public Duck(){
    };
    public abstract void display();

    public void performFly(){
        flyBehavior.fly();
    }
    public void performQuack(){
        quackBehavior.quack();
    }
    //动态设定飞行行为
    public void setFlyBehavior(FlyBehavior fb){
        flyBehavior = fb;
    }
    //动态设定鸣叫行为
    public void setQuackBehavior(QuackBehavior qb){
        quackBehavior = qb;
    }
    public void swim(){
        System.out.println("All ducks float, even decoys");
    }
}

//飞行接口
public interface FlyBehavior {
    public void fly();
}

//鸣叫接口
public interface QuackBehavior {
    public void quack();
}
//翅膀飞行类
public class FlyWithWings implements  FlyBehavior {
    public void fly(){
        System.out.println("i am flying");
    }

}
//不会飞类
public class FlyNoWay implements FlyBehavior {
    public void fly(){
        System.out.println("I can not fly");
    }
}
//鸭叫类
public class Quack implements QuackBehavior {
    public void quack(){
        System.out.println("I am quacking");
    }
}
//不能叫类
public class MuteQuack implements QuackBehavior{
    public void quack(){
        System.out.println("I can not quack");
    }
}
//吱吱叫类
public class Squeak implements QuackBehavior{
   public void quack(){
       System.out.println("squeak");
   }
}
//野鸭类
public class MallardDuck extends Duck {
    public  MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }
    public void display(){
        System.out.println("i am a real mallardduck");
    }
}
//测试类
public class MiniDuckSimulator {
    public static void main(String[] args){
        Duck mallard = new MallardDuck();
        if (mallard == null){
            System.out.println("mallard is null");
        }
        mallard.performFly();
        mallard.performQuack();
    }
}
整体格局

整体格局

上面代码实现的就是我们的第一个模式——策略模式

策略模式:

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

猜你喜欢

转载自blog.csdn.net/guojunxiu/article/details/81902604