深度解析策略模式:从理论到企业级实战应用
一、策略模式的本质:面向接口的算法工厂
策略模式(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机制 | 
| 策略执行顺序依赖 | 策略之间存在依赖关系 | 引入策略责任链模式 | 
