模式定义
策略模式是一种软件设计模式,它可以在运行时动态的选择算法的行为。
例如:现在我们要完成一件事情,可以有多重策略,如策略A、策略B、策略C等。我们的需求是想要在不同的情况下选择使用不同的策略。在Java中,我们可以使用多态来实现这个功能。策略模式还体现了面向接口而不是面向实现来编程的原则。
示例说明
如下图所示,我们需要完成一个屠龙的任务。屠龙者(DragonSlayer)可以有三种策略来完成这个任务,分别为ProjectileStrategy、MeleeStrategy、SpellStrategy。DragonSlayer可以在运行时动态的选择这三种策略来完成屠龙的任务。
类之间的关系图如下所示:

可以看出,这三种策略都实现了DragonSlayingStrategy这个接口,这个接口定义了一个execute的方法。
代码说明
1  | /**  | 
MeleeStrategy:1
2
3
4
5
6
7
8
9
10public class MeleeStrategy implements DragonSlayingStrategy {
  private static final Logger LOGGER = LoggerFactory.getLogger(MeleeStrategy.class);
  
  public void execute() {
      //用你的神剑,你切断了龙的头!
    LOGGER.info("With your Excalibur you sever the dragon's head!");
  }
}
ProjectileStrategy:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
 * 
 * Projectile strategy.
 *
 */
public class ProjectileStrategy implements DragonSlayingStrategy {
  private static final Logger LOGGER = LoggerFactory.getLogger(ProjectileStrategy.class);
  
  public void execute() {
      //你用神奇的弩向龙射击,它倒在地上!
    LOGGER.info("You shoot the dragon with the magical crossbow and it falls dead on the ground!");
  }
}
SpellStrategy:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
 * 
 * Spell strategy.
 *
 */
public class SpellStrategy implements DragonSlayingStrategy {
  private static final Logger LOGGER = LoggerFactory.getLogger(SpellStrategy.class);
  
  public void execute() {
      //你施放了瓦解的魔咒,龙在一堆尘埃中蒸发了!
    LOGGER.info("You cast the spell of disintegration and the dragon vaporizes in a pile of dust!");
  }
}
下面来看看如何使用这三个策略,DragonSlayer 这个类通过组合的方式在自己的内部持有了一个策略。注意的是,该策略是一个接口,而没有具体指定是哪一个策略。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class DragonSlayer {
    //持有了一个策略,并通过构造函数来初始化
  private DragonSlayingStrategy strategy;
  public DragonSlayer(DragonSlayingStrategy strategy) {
    this.strategy = strategy;
  }
//改变策略
  public void changeStrategy(DragonSlayingStrategy strategy) {
    this.strategy = strategy;
  }
//战斗吧, 哈哈!
  public void goToBattle() {
    strategy.execute();
  }
}
1  | public static void main(String[] args) {  | 
输出:1
2
3
4
5
611:02:32.567 [main] INFO com.iluwatar.strategy.App - Green dragon spotted ahead!
11:02:32.616 [main] INFO com.iluwatar.strategy.App - With your Excalibur you severe the dragon's head!
11:02:32.616 [main] INFO com.iluwatar.strategy.App - Red dragon emerges.
11:02:32.616 [main] INFO com.iluwatar.strategy.App - You shoot the dragon with the magical crossbow and it falls dead on the ground!
11:02:32.616 [main] INFO com.iluwatar.strategy.App - Black dragon lands before you.
11:02:32.616 [main] INFO com.iluwatar.strategy.App - You cast the spell of disintegration and the dragon vaporizes in a pile of dust!