一、策略模式的本质:面向接口的算法工厂
策略模式(Strategy Pattern)是行为型设计模式的典型代表,其核心思想是将算法族抽象为独立对象,使其能够相互替换。这种模式完美体现了以下面向对象设计原则:
-
开闭原则(OCP):新增策略无需修改已有代码
-
单一职责原则(SRP):每个策略只负责特定算法
-
依赖倒置原则(DIP):高层模块依赖抽象而非具体实现
UML类图:
![](https://i-blog.csdnimg.cn/direct/08900b3025084d8b98b15921c3c5fcf0.png)
二、策略模式的三种典型实现方式
1. 基础版实现(传统方式)
// 策略接口
public interface DiscountStrategy {
BigDecimal calculateDiscount(BigDecimal amount);
}
// 具体策略
public class VipDiscount implements DiscountStrategy {
@Override
public BigDecimal calculateDiscount(BigDecimal amount) {
return amount.multiply(new BigDecimal("0.8"));
}
}
public class FestivalDiscount implements DiscountStrategy {
@Override
public BigDecimal calculateDiscount(BigDecimal amount) {
return amount.subtract(new BigDecimal("50"));
}
}
// 上下文环境
public class OrderContext {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public BigDecimal executeDiscount(BigDecimal amount) {
return strategy.calculateDiscount(amount);
}
}
2. 枚举策略(简化分支判断)
public enum CalculatorStrategy {
ADD {
@Override
public int execute(int a, int b) { return a + b; }
},
SUBTRACT {
@Override
public int execute(int a, int b) { return a - b; }
};
public abstract int execute(int a, int b);
}
3. Spring集成版(企业级实践)
// 定义策略接口
public interface PaymentStrategy {
void processPayment(BigDecimal amount);
}
// 实现策略(带Spring注解)
@Component("alipayStrategy")
public class AlipayStrategy implements PaymentStrategy {
@Override
public void processPayment(BigDecimal amount) {
// 支付宝支付逻辑
}
}
@Component("wechatPayStrategy")
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void processPayment(BigDecimal amount) {
// 微信支付逻辑
}
}
// 策略上下文(自动注入策略集合)
@Service
public class PaymentContext {
@Autowired
private Map<String, PaymentStrategy> strategyMap;
public void executePayment(String paymentType, BigDecimal amount) {
PaymentStrategy strategy = strategyMap.get(paymentType + "Strategy");
if (strategy != null) {
strategy.processPayment(amount);
} else {
throw new IllegalArgumentException("Unsupported payment type");
}
}
}
三、策略模式的六大应用场景
场景1:电商促销系统
-
满减策略
-
折扣策略
-
赠品策略
-
积分抵现策略
场景2:支付网关路由
-
支付宝支付
-
微信支付
-
银联支付
-
数字货币支付
场景3:日志处理系统
-
本地文件存储
-
云存储(OSS/S3)
-
消息队列转发
-
数据库存储
场景4:数据校验引擎
-
手机号校验
-
身份证校验
-
邮箱校验
-
地址校验
场景5:游戏AI系统
-
攻击策略
-
防御策略
-
逃跑策略
-
补给策略
场景6:报表生成系统
-
PDF生成
-
Excel生成
-
HTML生成
-
CSV生成
四、策略模式与相关模式的深度对比
模式 | 关注点 | 与策略模式的关系 |
---|---|---|
工厂模式 | 对象创建 | 策略模式常配合工厂创建具体策略 |
状态模式 | 状态转换 | 状态改变行为,策略改变算法 |
模板方法模式 | 算法步骤 | 策略替换整个算法,模板方法替换步骤 |
命令模式 | 请求封装 | 策略是主动选择,命令是被动触发 |
五、企业级实战:支付系统策略架构设计
架构图
复制
[支付请求] --> [支付网关]
↓
[策略路由中心]
↓
+----------------+----------------+
| 支付宝策略 | 微信支付策略 | 银联策略
+----------------+----------------+
↓
[渠道适配层]
↓
[第三方支付平台]
代码实现(Spring Boot +策略模式)
java
复制
// 支付策略接口
public interface PaymentStrategy {
PaymentResult pay(PaymentRequest request);
}
// 支付宝策略实现
@Component
public class AlipayStrategy implements PaymentStrategy {
@Override
@PaymentType(PayChannel.ALIPAY)
public PaymentResult pay(PaymentRequest request) {
// 调用支付宝SDK
return new PaymentResult(true, "ALIPAY-123456");
}
}
// 策略工厂(自动发现策略)
@Component
public class PaymentStrategyFactory {
@Autowired
private Map<String, PaymentStrategy> strategyMap;
public PaymentStrategy getStrategy(PayChannel channel) {
return strategyMap.values().stream()
.filter(s -> s.getClass().isAnnotationPresent(PaymentType.class))
.filter(s -> s.getClass().getAnnotation(PaymentType.class).value() == channel)
.findFirst()
.orElseThrow(() -> new RuntimeException("未找到支付策略"));
}
}
// 支付服务
@Service
@RequiredArgsConstructor
public class PaymentService {
private final PaymentStrategyFactory strategyFactory;
public PaymentResult processPayment(PaymentRequest request) {
PaymentStrategy strategy = strategyFactory.getStrategy(request.getChannel());
return strategy.pay(request);
}
}
六、策略模式的五个优化技巧
1. 策略预热缓存
public class StrategyCache {
private static final Map<String, Strategy> cache = new ConcurrentHashMap<>();
public static Strategy getStrategy(String type) {
return cache.computeIfAbsent(type, t -> {
// 动态加载策略类
try {
return (Strategy) Class.forName(t).newInstance();
} catch (Exception e) {
throw new RuntimeException("策略加载失败");
}
});
}
}
2. 策略权重配置
# application.yml
payment:
strategies:
alipay:
weight: 60
enable: true
wechat:
weight: 30
enable: true
unionpay:
weight: 10
enable: false
3. 策略性能监控
public class MonitoredStrategy implements Strategy {
private final Strategy delegate;
private final MeterRegistry registry;
public MonitoredStrategy(Strategy delegate, MeterRegistry registry) {
this.delegate = delegate;
this.registry = registry;
}
@Override
public void execute() {
Timer.Sample sample = Timer.start(registry);
try {
delegate.execute();
} finally {
sample.stop(registry.timer("strategy.execution.time", "type", delegate.getClass().getSimpleName()));
}
}
}
七、常见陷阱与解决方案
陷阱 | 现象 | 解决方案 |
---|---|---|
策略状态共享 | 线程安全问题 | 使用ThreadLocal或每次新建策略实例 |
策略膨胀失控 | 类数量爆炸 | 使用DSL动态生成策略类 |
策略切换开销大 | 频繁切换影响性能 | 引入策略缓存池 |
策略配置错误 | 运行时找不到策略 | 增加策略fallback机制 |
策略执行顺序依赖 | 策略之间存在依赖关系 | 引入策略责任链模式 |