策略模式详解:将 if-else 转化为可切换算法
策略模式是一种行为型设计模式,旨在解决 if-else 条件分支过多导致代码难以维护的问题。通过将一系列算法封装成独立的策略类,并在运行时动态切换,该模式实现了算法与使用算法的客户端解耦。核心结构包括策略接口、具体策略类和上下文。其优点在于符合开闭原则,便于扩展新规则;缺点是增加了类的数量。适用于规则引擎、支付策略及排序算法等场景。JDK 中的 Comparator 也是策略模式的典型应用。

策略模式是一种行为型设计模式,旨在解决 if-else 条件分支过多导致代码难以维护的问题。通过将一系列算法封装成独立的策略类,并在运行时动态切换,该模式实现了算法与使用算法的客户端解耦。核心结构包括策略接口、具体策略类和上下文。其优点在于符合开闭原则,便于扩展新规则;缺点是增加了类的数量。适用于规则引擎、支付策略及排序算法等场景。JDK 中的 Comparator 也是策略模式的典型应用。

在实际项目中,你很可能见过这样的代码:
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;
}
问题非常明显:
当条件分支开始膨胀时,策略模式就是最优解。
定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
详解:策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
一句话理解:
把算法当成对象来用。
策略模式的本质是:
它强调:
用组合代替条件判断。
策略模式包含三个角色:
这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
实现了抽象策略定义的接口,提供具体的算法实现或行为。
持有一个策略类的引用,最终给客户端调用。
public interface PriceStrategy {
double calculate(double price);
}
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;
}
}
public class PriceContext {
private PriceStrategy strategy;
public PriceContext(PriceStrategy strategy) {
this.strategy = strategy;
}
public double getFinalPrice(double price) {
return strategy.calculate(price);
}
}
PriceContext context = new PriceContext(new VipPriceStrategy());
System.out.println(context.getFinalPrice(100));
运行时随意切换算法。
| 维度 | 策略模式 | 模板方法 |
|---|---|---|
| 技术手段 | 组合 | 继承 |
| 切换方式 | 运行期 | 编译期 |
| 灵活性 | 高 | 中 |
Collections.sort(list, comparator);
排序算法不变,比较规则可切换。
策略模式不是为了'多写类',而是为了'少写条件判断'。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online