背景介绍:一个关于鸭子的游戏:有各种鸭子,一边游泳戏水,一边呱呱叫。此系统内部设计了一个鸭子超类,并让所有的鸭子继承此超类。
关系图:
需求:让部分鸭子可以飞(如,橡皮鸭,诱饵鸭等)。
原设计方法:在超类上增加fly(),在子类不可以飞的鸭子(如,橡皮鸭)中,覆盖fly()方法,方法里什么都不做。
问题:其他不会飞的鸭子都要重写一个空的fly()方法,修改代码重复,且过多。
解决方法:分开变化和不变化的部分
提供飞和叫的行为接口,鸭子的所有行为被放在分开的类中,此类专门提供某行为接口的实现。
鸭子,将行为动作委托给别人处理
具体实现代码:
Duck超类:
public abstract class Duck {
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
public abstract void display();
public void performFly() {
flyBehavior.fly();
}
public void perforQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior= fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
}
鸭子行为接口:
FlyBehavior
public interface FlyBehavior {
public void fly();
}
QuackBehavior
public interface QuackBehavior {
void quack();
}
可以飞的:
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying!");
}
}
不可以飞的:public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("I can't fly!");
}
}
会呱呱叫的: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 ModelDuck extends Duck {
public void display() {
System.out.println("iam a model duck");
}
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
}
会飞会叫的鸭子:
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display() {
System.out.println("I'm a really Mallard duck");
}
}
测试:
public class MiniDuckSimular {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.perforQuack();
mallard.performFly();
System.out.println("---------------");
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyWithWings());
model.performFly();
}
}
测试结果:
总结:
策略模式--定义算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。