设计模式之策略模式

策略模式

     最近买了一本关于java设计模式的新书《Head First 设计模式》,里面介绍了java 的23种设计模式。目前看了第一章介绍的策略模式,里面的内容很容易理解,但是让我自己用嘴说出来却又总感觉表达不是很清楚。正所谓温故知新,所以我打算把自己的理解以及书上的代码记录到这里,算是一个回顾的过程。

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

    这本书上介绍策略模式使用的是一个鸭子的对象,其中鸭子有很多属性:飞行、鸣叫、展现形式等。由于要做一个通用的鸭子对象模型,所以我们需要把把这个鸭子创建成一个抽象的对象,将所有鸭子的通用属性放在抽象类中,而将差异化的属性在继承类中实现。考虑到代码的可扩展性和后期的维护,又将继承的这种模式进行改变,将两个类结合起来使用,即组合的方式。这种做法和继承不同的地方在于,鸭子的行为不是继承来的,而是和适当行为对象“组合”来的。使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可。

设计原则:多用组合,少用继承。

先来一张整体设计图:


设计模式之策略模式_第1张图片

这张图展示了利用策略模式对鸭子对象的属性进行拆分和组合,将鸭子的飞行和鸣叫的行为委托给接口来处理,而固定属性则封装在抽象类中。

上代码:

Duck类

package com.my.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 swim(){
        System.out.println("All  ducks float,even decoys!");
    }

    public void setFlyBehavior(FlyBehavior fb){//提供动态改变飞行行为的方法

        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb){//提供动态改变鸣叫行为的方法
        quackBehavior = qb;
    }
}
FlyBehavior类

package com.my.duck;

public interface FlyBehavior {
    public void fly();//所有飞行行为类必须实现的接口
}
FlyBehavior的实现

package com.my.duck;

public class FlyWithWings implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I'm flying !");
    }
}
package com.my.duck;

public class FlyNoWay implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I can't fly");
    }
}
QuackBehavior接口

package com.my.duck;

public interface QuackBehavior {
    public void quack();
}
QuackBehavior实现

package com.my.duck;

public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Quack");
    }
}
package com.my.duck;

public class MuteQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("<>");
    }
}
package com.my.duck;

public class Squeak implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Squeak");
    }
}

新建一个模型鸭子(ModelDuck)

package com.my.duck;

public class ModelDuck extends Duck {
    public ModelDuck(){
        flyBehavior = new FlyNoWay();//一开始模型鸭子不会飞行
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a model Duck");
    }
}
运行函数:

package com.my.duck;

public class MiniDuckSimulator {
    public static void main(String[] args){
        /*Duck mallard = new MallardDuck();
        mallard.performFly();
        mallard.performQuack();*/

        Duck model = new ModelDuck();
        //第一次调用performFly()会被委托给flyBehavior对象(也就是FlyNoWay实例),该对象是在模型鸭构造器中设置的。
        model.performFly();
        //这会调用继承来的setter方法,把火箭动力飞行的行为设定到模型鸭子中。
        model.setFlyBehavior(new FlyRocketPowered());
        //鸭子的飞行方式将变成乘坐火箭飞行器飞行。
        model.performFly();
    }
}
运行效果:

设计模式之策略模式_第2张图片




你可能感兴趣的:(设计模式)