目标:理解策略模式如何替代复杂
if-else,让规则扩展更平滑、代码更易维护。
策略模式:把一组可互换的算法(规则)分别封装起来,在运行时按需选择具体策略执行。
直接 if-else 在小场景没问题,但当规则增多时会出现典型痛点:
适合继续 if-else 的情况:
适合策略模式的情况:
真实业务中高频出现策略模式:
下面用“订单优惠计算”演示。
import java.math.BigDecimal;
public interface DiscountStrategy {
BigDecimal apply(BigDecimal originalAmount);
}import java.math.BigDecimal;
public class NoDiscountStrategy implements DiscountStrategy {
@Override
public BigDecimal apply(BigDecimal originalAmount) {
return originalAmount;
}
}import java.math.BigDecimal;
public class PercentageDiscountStrategy implements DiscountStrategy {
private final BigDecimal rate; // 例如 0.9 代表 9 折
public PercentageDiscountStrategy(BigDecimal rate) {
this.rate = rate;
}
@Override
public BigDecimal apply(BigDecimal originalAmount) {
return originalAmount.multiply(rate);
}
}import java.math.BigDecimal;
public class FullReductionStrategy implements DiscountStrategy {
private final BigDecimal threshold;
private final BigDecimal reduction;
public FullReductionStrategy(BigDecimal threshold, BigDecimal reduction) {
this.threshold = threshold;
this.reduction = reduction;
}
@Override
public BigDecimal apply(BigDecimal originalAmount) {
if (originalAmount.compareTo(threshold) >= 0) {
return originalAmount.subtract(reduction);
}
return originalAmount;
}
}import java.math.BigDecimal;
public class DiscountContext {
private DiscountStrategy strategy;
public DiscountContext(DiscountStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public BigDecimal calculate(BigDecimal amount) {
return strategy.apply(amount);
}
}import java.math.BigDecimal;
public class StrategyDemo {
public static void main(String[] args) {
BigDecimal amount = new BigDecimal("299");
DiscountContext context = new DiscountContext(new NoDiscountStrategy());
System.out.println("无优惠: " + context.calculate(amount));
context.setStrategy(new PercentageDiscountStrategy(new BigDecimal("0.9")));
System.out.println("9折后: " + context.calculate(amount));
context.setStrategy(new FullReductionStrategy(
new BigDecimal("200"),
new BigDecimal("30")
));
System.out.println("满减后: " + context.calculate(amount));
}
}if-else,逻辑更清晰Comparator:典型策略接口,传入不同比较策略即可改变排序行为。list.sort((a, b) -> a.getAge() - b.getAge()); // 一种策略
list.sort((a, b) -> a.getName().compareTo(b.getName())); // 另一种策略Resource 体系、HandlerMethodArgumentResolver 等场景,本质也是“面向接口 + 多实现 + 运行时选择”。flowchart LR
A["业务请求"] --> B["策略上下文"]
B --> C{"选择策略"}
C --> D["策略A"]
C --> E["策略B"]
C --> F["策略C"]
D --> G["返回结果"]
E --> G
F --> G
常见组合:用工厂创建策略,再交给上下文执行。
if-else 业务逻辑重构为策略模式。if-else 持续膨胀,就是策略模式该上场的信号。