1、策略模式的定义
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
2、鸭子设计
2.1 需求
定义绿头鸭,红头鸭,橡胶鸭,诱饵鸭(前俩个都是普通鸭子,外观不同,橡胶鸭不会飞,诱饵鸭不会飞也不会叫)
2.2 设计方式1(一般实现)
这种设计应该说是我们大多数人下意识都会想到的,既通过超类抽取了游泳和外观的方法(继承抽取共性,所有的鸭子都会游泳,所有的鸭子都有外貌,当然fly()方法和quack()方法也可以抽取到父类中,子类重写,但是你要这么写,可能你的上司就要找你谈心让你回炉重造了),又通过接口来实现不同鸭子的不同需求(诱饵鸭不会飞就不实现Flyable接口,橡胶鸭呱呱叫就实现Quackable接口。
当我第一次看到这个设计的时候,觉得没毛病,如果是我的话我也会这么做,可是它实在不是一个值得称赞的设计。
2.3 设计方式2 (优化)
①很明显,这样设计增加了我们的代码量(多了两个类实现接口),但是这样做飞行动作和呱呱叫的动作就可以复用了,不必再被迫关联到鸭子超类。
②此外,我们可以动态增加一些行为,又不会对原有的行为造成影响。
3、代码实现
①实现鸭子的基本逻辑
public abstract class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior; public Duck() { // TODO Auto-generated constructor stub } public abstract void display(); public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println("All ducks float, even decoys!"); } }
public interface FlyBehavior { public void fly(); }
public class FlyNoWay implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can't fly"); } }
public class FlyWithWings implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can fly"); } }
public interface QuackBehavior { public void quack(); }
public interface QuackBehavior { public void quack(); }
public class Squeak implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("squeak"); } }
public class MuteQuack implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("silence"); } }
public class MallardDuck extends Duck{ public MallardDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm a real Mallard duck"); } }
MallardDuck
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallark = new MallardDuck();
mallark.performFly();
mallark.performQuack();
}
}
运行结果
I can fly
Quack
②动态设定鸭子的行为
Duck类中新增set方法
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
定义鸭子类型模型鸭
public class ModelDuck extends Duck { public ModelDuck() { // TODO Auto-generated constructor stub flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); } @Override public void display() { // TODO Auto-generated method stub System.out.println("I'm a model duck"); } }
定义火箭飞行行为
public class FlyRocketPowered implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("I'm flying with a rocket"); //定义火箭飞行 } }
改变测试类
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallark = new MallardDuck();
mallark.performFly();
mallark.performQuack();
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered()); //动态设定行为
model.performFly();
}
}
运行结果
I can fly
Quack
I can't fly
I'm flying with a rocket
设计总览
4.小结
这个是书上的例子,它很全面但是它不好,它讲得不清楚,更不易理解,虽然结合实际但是看了还是让人不知道什么时候用。所以暂时先放在这里,过段时间写篇易理解的。这篇着实难懂,但我还是不会删它,因为理解了策略模式,你只会觉得这篇just so so.