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