策略模式

来源:互联网 发布:vr软件看不了 编辑:程序博客网 时间:2024/06/05 17:16

注: 摘自 《Head First 设计模式》, 可以自行找原书看。

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

使用到的OO设计原则:

1 . 找出应用中需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。
下面的例子中,鸭子有飞行的行为是不变的部分,而不同的飞行方式是 可变的部分 , 我们可以将分开变化和不会变化的部分。
2 . 多用组合, 少用继承。

用代码说明一下:

场景: 我们公司现在需要设计一个Duck类,它有各种子类: 红头鸭,绿头鸭,橡胶鸭,模型鸭。 Duck类也有各种行为和属性: 叫声 , 飞行 ,游泳 , 样子。如: 橡胶鸭 会叫 不会飞

策略模式的结构:

这里写图片描述
Duck抽象类

public abstract class Duck {    FlyBehavior flyBehavior;  // 飞行行为  是 代码中不可变的部分    QuackBehavor quackBehavor;  // 叫声行为    public Duck(){}    public abstract void display();  // 描述    public void performFly(){         performFly.fly();    //   具体的飞行方式  是 代码中可变的部分    }    public void performQuack(){        quackBehavior.quack();    }    public void swim() {        System.out.println("All ducks floats, even decoys!"); // 所有鸭子都会游泳    }}

Duck类

public class MallardDuck extends Duck {    public MallardDuck(){        // 使用多态,在创建子类时,自定义鸭子的行为方式        quackBehavior = new Quack();             flyBehavior = new FlyWithWings();    }    public void display() {        System.out.println("I'm a real Mallard duck ");   //  对鸭子进行描述    }}

输入并编译FlyBehavior接口(FlyBehavior.java) 与俩个行为实现类(FlyWithWings.java与FlyNoWay.java)

FlyBeHavivor.java

public interface FlyBehavior {         // 为了可以使用多态,在创建子类时,自定义鸭子的行为方式    public void fly();}

public class FlyWithWings implements FlyBehavior {    public void fly() {            System.out.println("I'm flying");  // 可以飞    }}
public class FlyNoWay implements FlyBehavior {    public void fly() {        System.out.println("I can't fly");  // 不能飞    }}

输入并编写QuackBehavior接口(QuackBehavior.java) 以及三个实现类(Quack.java、MuteQuack.java、Squack.java)

public interface QuackBehavior {     public void quack();}

public class Quack implements QuackBehavior {    public void quack() {            System.out.println("Quack");     }}
public class MuteQuack implements QuackBehavior {    public void quack() {            System.out.println("<Silence>");    }}
public class Squack implements QuackBehavior {    public void quack() {            System.out.println("Squack");    }}

测试类:

public class MiniDuckSimulator {    public void main(String[] args){        Duck mallard = new MallardDuck();        mallard.performQuack();         mallard.performFly();    }}
测试结果:Quack     I'm flying!!

进阶:动态设定Duck的行为

1 . 在Duck类中,加入俩个新方法

public void setFlyBehavior(FlyBehavior fb) {    flyBehavor = fb;}public void setQuackBehavior (QuackckBehavior qb) {    quackBehavior = qb;}

2 . 我们制造一个新的鸭子类型: 模型鸭(MoadlDuck.java) , 模型鸭是不会飞的

public class ModelDuck extends Duck {    public ModelDuck() {        flyBehavior = new FlyNoWay();  // 不会飞        quackBehavior = new Quack();    }    public void display() {        System.out.println("I am a medel duck.")    }}

3 . 建立一个新的FlyBehavior 类型 (FlyRocketPowered.java)

public class FlyRocketPowered implements FlyBehavior {    public void fly() {        System.out.println(" I am flying with a rocket !"); //利用火箭我们就可以让模型鸭有了飞行行为。    }}

4 . 测试类

public class MiniDuckSimulator {    public static void main(String[] args) {        Duck mallard = new MallardDuck();        mallard.performQuack();        mallard.performFly();        Duck model = new ModelDuck();        model.performFly();      // 不会飞        model.setFlyBehavior(new FlyRocketPowered()); // 设置使用火箭飞行行为        model.performFly();    // 使用火箭飞行    }}
测试结果: Quack.I'm flying.I can't fly.I'm fiying with a rocket!
原创粉丝点击