深度解析策略模式:从理论到企业级实战应用

一、策略模式的本质:面向接口的算法工厂

策略模式(Strategy Pattern)是行为型设计模式的典型代表,其核心思想是将算法族抽象为独立对象,使其能够相互替换。这种模式完美体现了以下面向对象设计原则:

  1. 开闭原则(OCP):新增策略无需修改已有代码

  2. 单一职责原则(SRP):每个策略只负责特定算法

  3. 依赖倒置原则(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机制
策略执行顺序依赖 策略之间存在依赖关系 引入策略责任链模式
相关推荐
天上掉下来个程小白2 分钟前
Redis-12.在Java中操作Redis-Spring Data Redis使用方式-操作字符串类型的数据
java·redis·spring·springboot·苍穹外卖
在京奋斗者3 小时前
spring boot自动装配原理
java·spring boot·spring
胡图蛋.8 小时前
Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
java·spring boot·后端
吃海鲜的骆驼8 小时前
SpringBoot详细教程(持续更新中...)
java·spring boot·后端
迷雾骑士9 小时前
SpringBoot中WebMvcConfigurer注册多个拦截器(addInterceptors)时的顺序问题(二)
java·spring boot·后端·interceptor
半部论语10 小时前
SpringMVC 中的DispatcherServlet生命周期是否受Spring IOC 容器管理
java·后端·spring
计算机学长felix10 小时前
基于SpringBoot的“小说阅读平台”的设计与实现(源码+数据库+文档+PPT)
spring boot·毕业设计
快来卷java11 小时前
常见集合篇(二)数组、ArrayList与链表:原理、源码及业务场景深度解析
java·数据结构·链表·maven
小杨40411 小时前
springboot框架项目实践应用十三(springcloud alibaba整合sentinel)
spring boot·后端·spring cloud
ktkiko1111 小时前
用户模块——整合 Spring 缓存(Cacheable)
java·spring·缓存