策略模式(Strategy Pattern)

策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。(来自百度百科)

  策略模式的本质是:分离算法,选择实现。

 

问题:如何让一只玩具鸭子飞起来? 

  答:给这只鸭子装上火箭。

思考:鸭子类具有飞行的能力,玩具鸭是鸭子的子类,但是不具备飞行的能力,所以需要重写飞行的飞行方法。

假设:如果,我们不将飞行看成鸭子的一个方法,而是看成一个行为接口(QuackBehavior quackBehavior;) * 各种鸭子继承鸭子类后,实现不同的行为接口,就具有了各式各样的行为了。

 

1,鸭子抽象类,鸭子具有表现声音和飞行的能力,具体的表现取决于声音和飞行的行为,由具体实现类决定使用哪种行为

public abstract class Duck {
    QuackBehavior quackBehavior;   //鸭子叫的行为,
    FlyBehavior flyBehavior;      //飞行的行为

    public Duck() {
    }

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

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public abstract void display();

    public void performQuack(){
        quackBehavior.quack();
    }

    public void performFly(){
        flyBehavior.fly();
    }
}

2,野鸭子,继承鸭子抽象类

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

    public void display(){
        System.out.println("I am a real Mallard duck");
    }
}

 

3,模型鸭,继承鸭子抽象类

public class ModelDuck extends Duck {

    public ModelDuck() {
        flyBehavior = new FlyNoWay();
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I am a ModelDuck");
    }
}

 

4,行为接口,鸭子叫和飞行接口

public interface FlyBehavior {
    void fly();
}
public interface QuackBehavior {
    void quack();
}

 

5,鸭子叫接口实现类

1)正常呱呱叫

public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("真的呱呱叫");
    }
}

 

2)吱吱叫

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

 

3)不会叫的

public class MuteQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("不会叫");
    }
}

 

6,飞行接口实现类

1)正常用翅膀飞

public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("振翅高飞");
    }
}

 

2)用火箭飞

public class FlyRocketPowered implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I am fly with a rocket");
    }
}

 

3)不会飞

public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("不会飞");
    }
}

 

7,让模型鸭飞起来

public class MiniDuckSimulator {
    public static void main(String[] args) {
        Duck model = new ModelDuck();   //新建一个模型鸭
        model.display();                
        model.performFly();             //尝试飞行
        model.setFlyBehavior(new FlyRocketPowered());   //将飞行策略更换
        model.performFly();             //再次尝试飞行
    }
}

 

8,结果

I am a ModelDuck
不会飞
I am fly with a rocket

Process finished with exit code 0

 

 

缺点:

1,需要知道所有的策略类,并自行决定使用哪一个策略类。

2,策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

 

posted @ 2019-01-19 16:54  dioag  阅读(157)  评论(0编辑  收藏  举报