策略设计模式

模式定义

定义一系列算法,分别封装起来,让它们之间能够呼死去那个替换,此模式让算法变化,不会影响到使用算法的客户java

类图定义

示例

示例来自于Head First上的鸭子例子,一个鸭子的系统,系统中会出现不一样的鸭子,一边游泳一边叫。绿头鸭子会飞,会游泳,正常呱呱叫,橡皮鸭子不会飞不会游泳吱吱叫。后期可能会扩展其余的鸭子好比红头鸭子或者诱饵鸭。鸭子系统的设计类图以下
算法

首先建立鸭子类编程

/**
 * 鸭子抽象类
 *
 * @author Colin
 * @create 2018-02-25
 **/
public abstract class Duck {

    private FlyBehavior flyBehavior;
    private QuackBehavior quackBehavior;

    public Duck(){}

    /**
     * 外观显示方法
     */
    public abstract void display();

    public void swim(){
        System.out.println("咱们都是鸭子,咱们都会游泳!");
    }

    /**
     * 飞行
     */
    public void performFly(){
        flyBehavior.fly();
    }

    /**
     * 叫
     */
    public void  performQuack(){
        quackBehavior.quack();
    }

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

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

鸭子具体实现类ide

/**
 * 绿头鸭子
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class MallardDuck  extends Duck{
    @Override
    public void display() {
        System.out.println("我是绿头鸭子!");
    }
}
/**
 * 橡皮鸭子
 *
 * @author Colin
 * @create 2018-02-26
 **/
public class RebberDuck extends Duck {
    @Override
    public void display() {
        System.out.println("我是橡皮鸭子!");
    }
}

建立鸭子飞行和叫的接口和实现类,不一样的鸭子叫声或者是飞行的方式不同,因此相对于整个系统来讲这块是可变的,单独提取封装起来。测试

/**
 * 飞行行为
 *
 * @author Colin
 * @create 2018-02-25
 **/
public interface FlyBehavior {

    public void fly();
}


/**
 * 叫的行为
 *
 * @author Colin
 * @create 2018-02-25
 **/
public interface QuackBehavior {
    public void quack();
}
/**
 * 不会飞行
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("我不会飞!");
    }
}


/**
 * 飞行具体实现类
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("我会飞!");
    }
}
/**
 * 呱呱叫
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("正常鸭子呱呱叫!");
    }
}
/**
 * 吱吱叫
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class Squack implements QuackBehavior {

    @Override
    public void quack() {
        System.out.println("橡皮鸭子吱吱叫!");
    }
}

测试类this

/**
 * 鸭子测试类
 *
 * @author Colin
 * @create 2018-02-25
 **/
public class DuckTest {

    @Test
    public void testMallardDuck(){
        // 绿头鸭子会呱呱叫,会飞
        Duck duck=new MallardDuck();
        duck.setFlyBehavior(new FlyWithWings());
        duck.setQuackBehavior(new Quack());
        duck.display();
        duck.performFly();
        duck.performQuack();

    }
    @Test
    public void testRebberDuck(){
        Duck duck=new RebberDuck();
        duck.setFlyBehavior(new FlyNoWay());
        duck.setQuackBehavior(new Squack());
        duck.display();
        duck.performFly();
        duck.performQuack();
    }
}

总结

  • 上面的例子其实就是一个策略模式的应用,不一样的鸭子有不一样的飞行策略和叫的方式,因此单独定义飞行和叫的接口即策略模式中的策略接口,不一样的的叫声或者飞行方式实现接口即不一样的策略类。鸭子Duck类中组合这些策略,即Duck就是策略中的上下文,全部的变化行为都是在此定义。后期扩展其余鸭子时只需继承Duck 而后设定这个鸭子拥有的行为便可有很大的灵活性。设计

    涉及到的设计原则3d

  • 找出应用中可能须要变化之处,把它们独立出来,不要和那些不须要变化的代码混在一块儿
  • 针对接口编程,而不是针对实现编程(多态,利用多态程序能够针对超类编程执行时会根据实际的状况执行到真正的行为不会被绑死到超类型的行为上)
  • 多用组合,少用继承(使用组合系统具备很大的弹性,不只能够将算法封装成类更能够在运行时动态改变行为)code

相关文章
相关标签/搜索