在这里插入图片描述

1. 引言:if-else 正在失控

在实际项目中,你很可能见过这样的代码:

public double calculate(double price, String type) {
if ("VIP".equals(type)) {
return price * 0.8;
} else if ("SVIP".equals(type)) {
return price * 0.6;
} else if ("NORMAL".equals(type)) {
return price;
}
return price;
}

问题非常明显:

  • if-else 越来越长
  • 新规则要改老代码
  • 违反开闭原则

当条件分支开始膨胀时,策略模式就是最优解。有选择,就有策略。


2. 什么是策略模式

GoF 定义

定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。

详解:策略模式模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

一句话理解:

把算法当成对象来用。


3. 策略模式的核心思想

策略模式的本质是:

  • 行为抽象
  • 算法解耦
  • 运行期切换

它强调:

用组合代替条件判断。


4. 策略模式的结构

策略模式包含三个角色:

  1. Strategy(策略接口)类

这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  1. ConcreteStrategy(具体策略)类

实现了抽象策略定义的接口,提供具体的算法实现或行为。

  1. Context(上下文)

持有一个策略类的引用,最终给客户端调用。


5. 示例:商品价格计算

5.1 策略接口

public interface PriceStrategy {
double calculate(double price);
}

5.2 具体策略

public class NormalPriceStrategy implements PriceStrategy {
public double calculate(double price) {
return price;
}
}
public class VipPriceStrategy implements PriceStrategy {
public double calculate(double price) {
return price * 0.8;
}
}
public class SvipPriceStrategy implements PriceStrategy {
public double calculate(double price) {
return price * 0.6;
}
}

5.3 上下文

public class PriceContext {
private PriceStrategy strategy;
public PriceContext(PriceStrategy strategy) {
this.strategy = strategy;
}
public double getFinalPrice(double price) {
return strategy.calculate(price);
}
}

5.4 客户端使用

PriceContext context = new PriceContext(new VipPriceStrategy());
System.out.println(context.getFinalPrice(100));

运行时随意切换算法。


6. 策略模式的优点

  1. 消除 if-else
  2. 算法可自由扩展
  3. 符合开闭原则
  4. 运行期灵活切换

7. 策略模式的缺点

  1. 类数量增加
  2. 客户端需理解策略
  3. 策略选择逻辑需额外管理

8. 策略 vs 模板方法

维度策略模式模板方法
技术手段组合继承
切换方式运行期编译期
灵活性

9. JDK 中的策略模式

Comparator

Collections.sort(list, comparator);

排序算法不变,比较规则可切换。


10. 适用场景

  • 规则引擎
  • 支付策略
  • 排序算法
  • 风控策略

11. 一个常见误区

策略模式不是为了“多写类”,而是为了“少写条件判断”。


参考

策略模式 | 菜鸟教程

《图解设计模式》

策略 - Java教程 - 廖雪峰的官方网站

策略设计模式