一、策略模式(Strategy Pattern)《HeadFirst设计模式》读书笔记

  1.假设有一个需求,要做一个模拟鸭子的应用。首先很自然的,我们会想到使用继承,先创建一个超类Duck,然后让不同类型的鸭子继承这个超类,复用Duck中的一些属性和功能。

  2.这时我们来了一个需求,要求给一个可达鸭添加会飞的功能,为了体现OO的思想,我们不在具体的类中添加功能,还是在Duck类中添加了一个fly()方法以提高代码的复用性。但这样会导致所有类型的鸭子都继承了fly()方法,就连橡皮鸭也会,这显然是不对的。

    (1)我们可以在橡皮鸭中重写fly()方法将他覆盖掉,但是以后越来越多的鸭子类型出现后,会导致每次都需要将子类中不需要继承父类的方法覆盖掉,不仅麻烦,整体的逻辑关系也不清晰。

    (2)我们可以建立一个Flyable接口,这样想要飞的鸭子只要实现这个接口就可以了。但是还是要在特定的子类中去写实现,同样会很麻烦,而且没有实现代码的复用。

  这个问题可以总结为:我们使用继承是想提高代码的复用性,但是有的子类又有自己的特殊需求,如何有条理的按需定制这些方法呢?

  3.使用组合:

    (1)我们可以将Duck超类中的内容分为两部分:变化的和不会变化的。所有鸭子都具有的特征和行为就是基本不会变化的,我们使用继承处理这一部分,如果以后这些行为需要改变,也只需要在Duck超类中改动就可以了;而fly()行为就是会变化的,不同类型的鸭子会有不同的飞行姿势,还可能不会飞,这一部分我们可以使用组合。

    (2)创建一个FlyBehavior接口,对于不同的飞行行为都实现这个接口,对应具体的实现类,如FlyWithWings,FlyNoWay。

public interface FlyBehavior {
    void fly();
}

public class FlyWithWings  implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("i can fly with wings");
    }
}

public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I can't fly");
    }
}

    (3)在Duck中以成员变量的方式组合我们想要的功能,声明成接口类型,如FlyBehavior。再写一个方法叫perfomFly(),在方法内调用FlyBehavior接口的fly()方法,这里又体现了多态的思想。

public abstract class Duck {
    private String color;
    FlyBehavior flyBehavior;
    abstract void display();
    //所有的鸭子都会游泳
    public void swim(){
        System.out.println("all ducks can swim");
    }
    //通过组合实现fly的功能
    public void performFly(){
        flyBehavior.fly();
    }
}

    而该成员变量接口具体的实例在子类创建对象时,通过构造方法传递进来(暂时,后面会用其他设计模式优化)。额外的也可以通过增加set()方法动态的改变鸭子的行为。

public class PsyDuck extends Duck {
    @Override
    void display() {
        System.out.println("I am a PsyDuck");
    }
    //暂时通过构造方法传入FlyBehavior的实现类
    public PsyDuck(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
}

   测试一下:

public class MainTest {
    public static void main(String[] args) {
        PsyDuck psyDuck = new PsyDuck(new FlyWithWings());
        psyDuck.performFly();
    }
}

    打印结果为:

  

    在上面的例子中我们就使用了策略模式。

 4.策略模式(Strategy Pattern):

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

    解释:刚刚我们写的FlyBehavior的两个实现类FlyWithWings和FlyNoWay就是一族算法,说白了就是一组行为,当需要不同具体行为的时候,他们之间可以替换,这些行为发生变化时并不会影响到Duck和它的子类,因为在Duck中我们是使用多态的方式通过接口声明的。

  5.总结:

    (1)将变化的部分封装起来

    (2)使用组合

    (3)使用多态,面向接口编程

posted @ 2020-06-09 14:36  ADvancedCZ  阅读(164)  评论(0编辑  收藏  举报