【设计模式】SpringBoot策略模式实战:告别if-else,实现支付场景的优雅解耦

📅 2026/7/15 13:19:54 👁️ 阅读次数 📝 编程学习
【设计模式】SpringBoot策略模式实战:告别if-else,实现支付场景的优雅解耦

1. 支付场景的if-else困境

每次看到满屏的if-else支付逻辑代码,我的血压就会飙升。去年接手的一个电商项目里,支付模块的代码长这样:

public String pay(String payType, Order order) { if ("wechat".equals(payType)) { // 微信支付30行校验逻辑 WechatPayService service = new WechatPayService(); return service.pay(order); } else if ("alipay".equals(payType)) { // 支付宝支付25行校验逻辑 AlipayPayService service = new AlipayPayService(); return service.pay(order); } else if ("unionpay".equals(payType)) { // 银联支付40行校验逻辑 UnionPayService service = new UnionPayService(); return service.pay(order); } throw new UnsupportedOperationException("不支持的支付方式"); }

这种代码至少有三大致命伤:维护成本高(新增支付方式要修改核心类)、可读性差(逻辑嵌套超过3层就难以理解)、测试困难(牵一发而动全身)。更可怕的是,当支付方式增加到10种时,这个方法的行数会突破300行,成为真正的"屎山代码"。

2. 策略模式的核心思想

策略模式的本质是将算法家族封装成独立类,让它们可以互相替换。就像玩《王者荣耀》选英雄——你不需要知道英雄的具体技能,只需要根据阵容选择合适的角色。

在支付场景中,策略模式的三个关键角色:

  • 策略接口(PaymentStrategy):定义支付操作的契约
  • 具体策略(WechatPayStrategy/AlipayPayStrategy):实现不同支付方式
  • 上下文环境(PaymentContext):持有策略引用并执行

传统实现方式需要手动维护策略映射关系,而SpringBoot的IoC容器让这一切变得优雅。通过@Autowired自动注入策略集合,我们可以实现零配置的策略路由。

3. SpringBoot整合策略模式实战

3.1 定义策略接口

首先创建支付策略接口,注意这里使用@Component标记策略名称:

public interface PaymentStrategy { String executePay(Order order); } @Component("wechatPay") public class WechatPayStrategy implements PaymentStrategy { @Override public String executePay(Order order) { // 微信支付具体实现 return "微信支付成功"; } } @Component("alipay") public class AlipayStrategy implements PaymentStrategy { @Override public String executePay(Order order) { // 支付宝支付具体实现 return "支付宝支付成功"; } }

3.2 自动装配策略路由

利用Spring的特性自动收集所有策略实现:

@Service public class PaymentRouter { private Map<String, PaymentStrategy> strategyMap; @Autowired public void setStrategies(List<PaymentStrategy> strategies) { strategyMap = strategies.stream() .collect(Collectors.toMap( s -> s.getClass().getAnnotation(Component.class).value(), Function.identity() )); } public String routePay(String payType, Order order) { PaymentStrategy strategy = strategyMap.get(payType); if (strategy == null) { throw new IllegalArgumentException("无效支付类型"); } return strategy.executePay(order); } }

3.3 客户端调用示例

在Controller中调用就像点外卖一样简单:

@RestController @RequestMapping("/payment") public class PaymentController { @Autowired private PaymentRouter paymentRouter; @PostMapping("/pay") public Result pay(@RequestParam String payType, @RequestBody Order order) { String result = paymentRouter.routePay(payType, order); return Result.success(result); } }

4. 高级优化技巧

4.1 策略预热缓存

对于高频调用的支付场景,可以在应用启动时预加载策略:

@PostConstruct public void initStrategies() { log.info("预加载支付策略: {}", strategyMap.keySet()); }

4.2 策略版本控制

通过自定义注解支持多版本策略:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Component public @interface PayVersion { String value(); // 策略版本号 } @PayVersion("v2") @Component public class WechatPayV2Strategy implements PaymentStrategy { // 新版微信支付实现 }

4.3 策略降级处理

为策略添加熔断机制:

@Slf4j @Component("unionPay") public class UnionPayStrategy implements PaymentStrategy { @Override public String executePay(Order order) { try { // 正常支付逻辑 } catch (Exception e) { log.error("银联支付失败", e); return "银联支付降级处理"; } } }

5. 策略模式VS其他方案

对比方案扩展性可读性复杂度适用场景
if-else简单场景
策略模式算法多变
工厂模式对象创建复杂
模板方法流程固定

在实际项目中,我经常将策略模式与责任链模式结合使用。比如先通过策略选择支付方式,再用责任链处理支付后的风控、通知等流程。这种组合拳能处理更复杂的业务场景。