一、策略模式的本质:面向接口的算法工厂
策略模式(Strategy Pattern)是行为型设计模式的典型代表,其核心思想是将算法族抽象为独立对象,使其能够相互替换。这种模式完美体现了以下面向对象设计原则:
开闭原则(OCP):新增策略无需修改已有代码
单一职责原则(SRP):每个策略只负责特定算法
依赖倒置原则(DIP):高层模块依赖抽象而非具体实现
UML类图:
二、策略模式的三种典型实现方式
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机制 |
策略执行顺序依赖 | 策略之间存在依赖关系 | 引入策略责任链模式 |