定义

策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户
**

设计原则

  • 找出应用中可能需要变化之处,把它们独立出来, 不要和那些不需要变化的代码混在一起
  • 针对接口编程,而不是针对实现编程

    针对接口编程的真正意思是”针对超类型编程”, 利用多态, 程序可以针对超类型编程, 执行时会根据实际状况执行到真正的行为,不会被绑死在超类型上; “针对超类型编程”可以更明确的说是变量的声明类型应该是超类型, 通常是一个抽象类或一个接口

  • 多用组合, 少用继承

案例

背景:鸭子有飞和叫两种行为, 不同的鸭子飞和叫的行为可能不同, 设计一个可拓展易维护的系统

1.父类抽取方法, 子类具体实现飞和叫的行为
缺点: 每加一个鸭子, 就要重新实现fly和quack方法, fly和quack有相同的无法重用
image.png

2.以FlyBehavior示例, 将飞的行为抽取出来, 面向接口编程, 接口可以有不同的飞行行为实现; Duck类中有FlyBehavior的实例(组合), 调用FlyBehavior接口的fly方法, 实际会在代码运行时执行FlyBehavior实现类的方法
而FlyBehavior的具体类型, 可以在MallardDuck构造时指定, 也可以在运行时set指定(动态设定行为)
此外, 这样设计后, FlyBehavior与Duck不再有关联, 飞机也可以使用FlyBehavior接口
image.png
Duck

  1. public abstract class Duck {
  2. FlyBehavior flyBehavior;
  3. public void performFly() {
  4. flyBehavior.fly();
  5. }
  6. public FlyBehavior getFlyBehavior() {
  7. return flyBehavior;
  8. }
  9. public void setFlyBehavior(FlyBehavior flyBehavior) {
  10. this.flyBehavior = flyBehavior;
  11. }
  12. }

MallardDuck

  1. public class MallardDuck extends Duck {
  2. public MallardDuck() {
  3. flyBehavior = new FlyHigh();
  4. }
  5. }

test

  1. @Test
  2. public void testStrategy() {
  3. MallardDuck mallardDuck = new MallardDuck();
  4. mallardDuck.performFly();
  5. mallardDuck.setFlyBehavior(new FlyDown());
  6. mallardDuck.performFly();
  7. }
  8. 结果:
  9. 飞高
  10. 飞低

把行为想象成算法族, 即容易理解概念
image.png