策略模式:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变法独立于使用算法的客户。
鸭子游戏:绿头鸭 可以游泳 呱呱叫 可以用翅膀飞
红头鸭 可以游泳 呱呱叫 可以用翅膀飞
橡皮鸭 可以游泳 吱吱叫 不可以飞
诱饵鸭 可以游泳 不可叫 不可以飞
设计原则一:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
这个例子中 游泳行为是不需要变化的行为 叫和飞是变化的行为。
鸭子现在将叫和飞的动作独立出去之后,需要委托(delegate)别人处理,而不再是定义在鸭子类的叫和飞的方法。
全局类的结构:
三个超类,如下:
Duck类:
package org.fkjava.策略模式.Duck; import org.fkjava.策略模式.Behavior.FlyBehavior; import org.fkjava.策略模式.Behavior.QuackBehavior; public abstract class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior; public void swim() //swim方法对于任何鸭子都一样 ,让子类鸭子继承这个方法 { System.out.println("这只鸭子正在游泳....."); } public abstract void display(); //display方法 对于每个鸭子来说,具体实现不同,定义为抽象方法,让子类鸭子自己去实现 public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void performFly() //fly方法 不同种类的鸭子,存在差异 ,委托flyBehavior对象实现 { flyBehavior.fly(); } public void performQuack() //quack方法 不同种类的鸭子,存在差异 ,委托quackBehavior对象实现 { quackBehavior.quack(); } }
FlyBehavior接口:
package org.fkjava.策略模式.Behavior; public interface FlyBehavior { public void fly(); }
Quack接口:
package org.fkjava.策略模式.Behavior; public interface QuackBehavior { public void quack(); }
具体实现类如下:
FlyWithWings 类实现 FlyBehavior 接口:
package org.fkjava.策略模式.Behavior; public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("这只鸭子在用翅膀飞翔...."); } }
FlyNoWay 类实现 FlyBehavior 接口:
package org.fkjava.策略模式.Behavior; public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("这只鸭子不能飞翔..."); } }
Quack类 ,Squeak类 ,Mute类 分别实现 QuackBehavior接口:
public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("这只鸭子在呱呱叫...."); } } public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("这只鸭子在吱吱叫..."); } } public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("这只鸭子不会叫..."); } }
GreenHeadDuck类 ,RedHeadDuck类 ,RubberDuck类 ,DecoyDuck类 继承 Duck类:
public class GreenHeadDuck extends Duck { @Override public void display() { System.out.println("看上去,这是一只绿头鸭..."); } } public class RedHeadDuck extends Duck { @Override public void display() { System.out.println("看上去,这是一只红头鸭..."); } } public class RubberDuck extends Duck { @Override public void display() { System.out.println("看上去,这是一只橡皮鸭..."); } } public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("这只鸭子在吱吱叫..."); } }
最后,写一个测试类,提供入口main方法:
public class TestClass { public static void main(String[] args) { Duck greenHeadDuck = new GreenHeadDuck(); greenHeadDuck.setFlyBehavior(new FlyWithWings()); greenHeadDuck.setQuackBehavior(new Quack()); greenHeadDuck.display(); greenHeadDuck.swim(); greenHeadDuck.performFly(); greenHeadDuck.performQuack(); System.out.println("**********************"); Duck redHeadDuck = new RedHeadDuck(); redHeadDuck.setFlyBehavior(new FlyWithWings()); redHeadDuck.setQuackBehavior(new Quack()); redHeadDuck.display(); redHeadDuck.swim(); redHeadDuck.performFly(); redHeadDuck.performQuack(); System.out.println("**********************"); Duck rubberDuck = new RubberDuck(); rubberDuck.setFlyBehavior(new FlyNoWay()); rubberDuck.setQuackBehavior(new Squeak()); rubberDuck.display(); rubberDuck.swim(); rubberDuck.performFly(); rubberDuck.performQuack(); System.out.println("**********************"); Duck decoyDuck = new RubberDuck(); decoyDuck.setFlyBehavior(new FlyNoWay()); decoyDuck.setQuackBehavior(new MuteQuack()); decoyDuck.display(); decoyDuck.swim(); decoyDuck.performFly(); decoyDuck.performQuack(); } }
运行结果: