定义
策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户
**
设计原则
- 找出应用中可能需要变化之处,把它们独立出来, 不要和那些不需要变化的代码混在一起
针对接口编程,而不是针对实现编程
针对接口编程的真正意思是”针对超类型编程”, 利用多态, 程序可以针对超类型编程, 执行时会根据实际状况执行到真正的行为,不会被绑死在超类型上; “针对超类型编程”可以更明确的说是变量的声明类型应该是超类型, 通常是一个抽象类或一个接口
多用组合, 少用继承
案例
背景:鸭子有飞和叫两种行为, 不同的鸭子飞和叫的行为可能不同, 设计一个可拓展易维护的系统
1.父类抽取方法, 子类具体实现飞和叫的行为
缺点: 每加一个鸭子, 就要重新实现fly和quack方法, fly和quack有相同的无法重用
2.以FlyBehavior示例, 将飞的行为抽取出来, 面向接口编程, 接口可以有不同的飞行行为实现; Duck类中有FlyBehavior的实例(组合), 调用FlyBehavior接口的fly方法, 实际会在代码运行时执行FlyBehavior实现类的方法
而FlyBehavior的具体类型, 可以在MallardDuck构造时指定, 也可以在运行时set指定(动态设定行为)
此外, 这样设计后, FlyBehavior与Duck不再有关联, 飞机也可以使用FlyBehavior接口
Duck
public abstract class Duck {
FlyBehavior flyBehavior;
public void performFly() {
flyBehavior.fly();
}
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
MallardDuck
public class MallardDuck extends Duck {
public MallardDuck() {
flyBehavior = new FlyHigh();
}
}
test
@Test
public void testStrategy() {
MallardDuck mallardDuck = new MallardDuck();
mallardDuck.performFly();
mallardDuck.setFlyBehavior(new FlyDown());
mallardDuck.performFly();
}
结果:
飞高
飞低
把行为想象成算法族, 即容易理解概念