定义
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
书中例子
书中使用了Duck类一步一步优化到策略模式。一开始使用继承来让不同类型的鸭子有不同的行为方法,但是发现会产生一个问题。如果一个塑料鸭继承了Duck类,那么他就会拥有一个飞行方法和一个叫的方法。这样熟料鸭就能飞了,这显然是不合理的。
于是书中首先使用了接口来解决这个问题,他将行为方法提到不同的接口,如:飞行行为(Flyable)、呱呱叫行为(Quackble),然后让Duck的每一个子类来实现这些接口。这就产生了另一个问题:如果要有48个Duck的子类就要创建48个子类,并且每加一个子类就要实现一次接口。
最终,在Duck类中添加行为接口作为变量,并在Duck类中创建对应的方法,来调用这些接口的实现方法。这样就可以在创建每个子类时,通过实例化不同的行为接口的实现类,使行为方法在不同的Duck子类中有不同的实现。
实现
1.首先实现Duck类
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBhavior(QuackBehavior qb) {
quackBehavior = qb;
}
public abstract void display();
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float, even docoys");
}
}
该类中有Flybehavior、quackBehavior两个行为接口。
2.分别实现这两个接口对应的类。如不能飞行,使用火箭飞行,滑翔等。(代码略)
3.在构造子类时将子类的Flybehavior和quackBehavior接口实例化
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display() {
System.out.println("I`m a real MallardDuck!!!!!");
}
}
这样就实现了运行时决定具体是哪个飞行方法或叫方法。
总结
设计原则
- 封装变化
- 多用组合,少用继承。
- 针对接口编程,不针对实现编程。