策略模式(Strategy Pattern)

  1. 什么是策略模式?
    定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
    那什么是算法族呢,现在听起来有点抽象,在后面的案例会将它实例化便于理解。

  2. 案例(参考Head First 设计模式):
    需求1.0:模拟鸭子,会游泳和呱呱叫。

public abstract class Duck {

    public void quck() {
        System.out.println("quck");
    }

    public void swim() {
        System.out.println("swim");
    }

    //每个鸭子的外观不同,所以是抽象方法
    public abstract void display();
}

实例一个鸭子:只是需要继承Duck即可,该类鸭子就可以游泳和呱呱叫。

public class MallardDuck extends Duck{

    @Override
    public void display() {
        System.out.println("绿头鸭");
    }
}

需求2.0:给鸭子添加飞行的行为。

idea 1.0:在Duck中添加fly的方法。

 public void fly() {
        System.out.println("fly");
    }

但是这样一来所有继承DucK的鸭子们都具有了fly的行为,包括那个不能飞的鸭子,比如小黄鸭,木头鸭等等。所以idea 1.0 Pass!

idea 2.0:将Duck中的fly方法覆盖,重写。

public class RubberDuck extends Duck {

    @Override
    public void fly() {
        //覆盖,什么都不做
    }

    @Override
    public void display() {
        System.out.println("我是橡皮鸭");
    }
}

idea 2.0看起来是解决了小黄鸭,木头鸭等鸭子不应该具有飞的行为的问题。但每次加入一次类似种类的鸭子都需要覆盖fly方法,而且如果今后想要再加入新的一种行为,那每一个子类都需要关注这个新进入的方法,是否要覆盖它。这样就会很麻烦。不仅fly方法,其实quck也会有类似问题,每个种类鸭子的叫声也是不一样的。所以idea 2.0也不适用。

idea 3.0:将fly和quack两个方法提取出来,成为两个接口InterfaceFly和InterfaceQuack。只有会飞的鸭子才继承fly的接口,去实现方法。根据idea 3.0示例一只鸭子将变成:

public class RedDuck extends Duck implements InterfaceFly,InterfaceQuack {

    @Override
    public void display() {
        System.out.println("我是红头鸭");
    }

    @Override
    public void fly() {
        System.out.println("fly");
    }

    @Override
    public void quack() {
        System.out.println("quack");
    }
}

idea 3.0问题显而易见,代码无法复用。跟idea 2.0的问题类似。

idea 4.0:将会变化的部分取出并封装起来,不要影响没有变化的部分。这句话的意思是:把鸭子的行为从Duck中取出来。创建两组类FlyBehavior和QuackBehavior,并且实现各自的方法。
fly类

public interface FlyBehavior {
    public void fly();
}
public class FlyNoWay  implements FlyBehavior{

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

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

Quack类

public interface QuackBehavior {
    public void quack();
}
public class MuteQuack implements QuackBehavior {

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

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

如果仅仅是这样又和idea 3.0有什么区别么,只是多了具体实现,如果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 duck float, even decoys");
    }

   //添加动态设置,可以动态改变飞的行为
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}

现在再次实例一个鸭子

public class MallardDuck extends Duck{

    public MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }

    @Override
    public void display() {
        System.out.println("I'm a real Mallard Duck");
    }
}

测试

 public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        mallard.display();
        mallard.performFly();
        mallard.performQuack();
        System.out.println("改变鸭子的叫声");
        mallard.setQuackBehavior(new MuteQuack());
        mallard.performQuack();
        mallard.swim();
    }
  /**
     * I'm a real Mallard Duck
     * I'm flying !!
     * Quack
     * 改变鸭子的叫声
     * <>
     * All duck float, even decoys
     */

  1. 白话总结
    根据案例,其实飞和叫的行为是可变的,而鸭子本身是不可变的,所以就要将两者分开,做到,一方改变不会影响另一方。这里面飞和叫的行为就是一开始所说的算法族。鸭子的行为被封装进入一组类中,可以被轻易地扩充与改变。如果需要在运行时也可以改变行为。

持续跟新中。。。。。。。

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