详细内容参见《HeadFirst设计模式》第一章 1设计模式入门欢迎来到设计模式世界
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)
以会“飞”和会“叫”的鸭子游戏为例。
1. 定义“飞”和“叫”的行为接口。
“飞”行为的接口类,只包含一个抽象的fly()方法。
public interface FlyBehavior { public void fly(); }
“叫”行为的接口类,只包含一个抽象的quack()方法。
public interface QuackBehavior { public void quack(); }
2. 定义鸭子的抽象基类。
包含“飞”行为和“叫”行为的两个实例变量,以为这两个实例变量的存取方法。抽象的display()方法,供子类去实现。最后,所有的鸭子都会游泳,swim()方法由子类去继承。
public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() { } public void setFlyBehavior (FlyBehavior fb) { flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; } abstract void display(); public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println("All ducks float, even decoys!"); } }
3. 实现一些具体的“飞”行为类。
public class FlyNoWay implements FlyBehavior { public void fly() { System.out.println("I can't fly"); } }
public class FlyWithWings implements FlyBehavior { public void fly() { System.out.println("I'm flying!!"); } }
public class FlyRocketPowered implements FlyBehavior { public void fly() { System.out.println("I'm flying with a rocket"); } }
4. 实现一些具体的“叫”行为类。
public class FakeQuack implements QuackBehavior { public void quack() { System.out.println("Qwak"); } }
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 Squeak implements QuackBehavior { public void quack() { System.out.println("Squeak"); } }
5. 实现一些具体的鸭子类。
public class DecoyDuck extends Duck { public DecoyDuck() { setFlyBehavior(new FlyNoWay()); setQuackBehavior(new MuteQuack()); } public void display() { System.out.println("I'm a duck Decoy"); } }
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"); } }
public class ModelDuck extends Duck { public ModelDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm a model duck"); } }
public class RedHeadDuck extends Duck { public RedHeadDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm a real Red Headed duck"); } }
public class RubberDuck extends Duck { public RubberDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Squeak(); } public void display() { System.out.println("I'm a rubber duckie"); } }
6. 总结设计原则。
(1) 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
(2) 针对接口编程,而不是针对实现编程。“针对接口编程”真正的意思是“针对超类型(supertype)编程”。
(3) 多用组合,少用继承。
7. 整个鸭子游戏系统的类图。
8. 测试代码。
public class MiniDuckSimulator1 { 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(); } }
public class MiniDuckSimulator { public static void main(String[] args) { MallardDuck mallard = new MallardDuck(); RubberDuck rubberDuckie = new RubberDuck(); DecoyDuck decoy = new DecoyDuck(); ModelDuck model = new ModelDuck(); mallard.performQuack(); rubberDuckie.performQuack(); decoy.performQuack(); model.performFly(); model.setFlyBehavior(new FlyRocketPowered()); model.performFly(); } }