尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

策略模式精讲+实战

策略模式精讲+实战
📅 发布时间:2026/7/3 15:03:51

策略模式(Strategy Pattern)精讲 —— 结合 Spring 实战

1. 官方标准定义(GoF 原话)

定义一组算法,将每个算法都封装起来,并且使它们之间可以互相替换。该模式让算法的变化独立于使用算法的客户端(调用方)。核心原则:针对接口编程,而不是针对实现编程。策略模式(Strategy Pattern)是 GoF 23 种设计模式中的行为型模式。

2. 一句话"人话"解读

它是一个策略路由器。你只需要告诉上下文(Context)你想要什么"策略标识"(比如"ALIPAY"),它就会自动把对应的"技能/算法"(比如支付宝支付逻辑)拿出来执行,而调用方完全不用关心底层是怎么if-else判断类型的。

3. 模式的核心三要素(结构定义)

为满足上面的定义,模式必须包含以下 3 个角色:

角色职责对应代码
抽象策略(Strategy)定义一个公共接口,所有算法都遵循这个"合同"PaymentStrategy接口
具体策略(ConcreteStrategy)实现接口的具体类,封装了具体的业务算法AlipayStrategy、WechatStrategy
上下文(Context)持有策略引用,负责根据条件路由到具体策略PaymentContext
设计原则
  • 封装变化:找出应用中可能需要变化的部分,把它们独立出来
  • 面向接口编程:策略的具体实现依赖接口,而不是依赖实现类
  • 组合优于继承:Context 通过组合持有一个 Strategy 引用,而不是继承具体策略
4. 为什么这个定义很重要?(结合 Spring 场景)
  • "互相替换":因为 Spring 把策略类注入了Map<String, Strategy>,只要type匹配,随时可以替换某个策略的实现类,调用方完全无感知。新增策略时,客户端代码完全不用改,完美符合"开闭原则"。
  • "变化独立于客户端":客户端(Controller)只需要传"WECHAT",不需要知道微信支付类是否被 AOP 代理了。无论注入的是原始类还是代理类,代码都能正常运行——这就是接口编程的威力。
5. 代码实战(解决支付场景)

假设有一个支付系统,支持支付宝、微信等多种渠道。我们将使用 Spring 的依赖注入特性来优雅实现。

5.1 原始反面案例(使用instanceof)
// ❌ 反面教材:每当新增支付方式,都要修改此处代码,违反开闭原则 public String pay(Object channel) { if (channel instanceof Alipay) { // 支付宝逻辑 } else if (channel instanceof WechatPay) { // 微信逻辑 } throw new UnsupportedOperationException(); }
5.2 重构为策略模式(优雅实现)
第一步:定义策略接口
public interface PaymentStrategy { // 策略标识(用于前端传参,替代 instanceof 判断) String getType(); // 执行支付 void pay(Double amount); }
第二步:实现具体策略(交给 Spring 管理)
@Component public class AlipayStrategy implements PaymentStrategy { @Override public String getType() { return "ALIPAY"; } @Override public void pay(Double amount) { System.out.println("使用支付宝支付:" + amount); // 此处调用支付宝 SDK... } } @Component public class WechatStrategy implements PaymentStrategy { @Override public String getType() { return "WECHAT"; } @Override public void pay(Double amount) { System.out.println("使用微信支付:" + amount); // 此处调用微信 SDK... } }
第三步:创建策略上下文(核心工厂)

利用 Spring 的构造函数注入,将所有的策略List自动转换为Map<String, Strategy>。此时已彻底消灭instanceof。

@Component public class PaymentContext { private final Map<String, PaymentStrategy> strategyMap; @Autowired public PaymentContext(List<PaymentStrategy> strategies) { // 将 List 转为 Map,Key 为策略自定义的类型标识 this.strategyMap = strategies.stream() .collect(Collectors.toMap(PaymentStrategy::getType, Function.identity())); } // 对外统一调用接口 public void executePay(String type, Double amount) { PaymentStrategy strategy = strategyMap.get(type); if (strategy == null) { throw new IllegalArgumentException("不支持的支付方式: " + type); } strategy.pay(amount); } }
第四步:Controller 层调用
@RestController @RequestMapping("/api/pay") public class PayController { @Autowired private PaymentContext paymentContext; @PostMapping public String pay(@RequestParam String type, @RequestParam Double amount) { // 前端传入 "ALIPAY" 或 "WECHAT",无需任何类型判断 paymentContext.executePay(type, amount); return "支付成功"; } }
6. 策略模式 vsinstanceof的优势
对比维度if-else+instanceof策略模式(Map 路由)
开闭原则违反(新增渠道需修改原有类)符合(新增渠道只需新建类加@Component)
代码可读性随着分支增多,逻辑臃肿难维护路由清晰,业务逻辑内聚在各自类中
测试难度需要 mock 大量无关分支可单独测试每个策略类
运行时性能链式判断,O(N) 复杂度Map 哈希查找,O(1) 复杂度
7. 联动避坑(Spring 代理问题)

如果具体策略类(如AlipayStrategy)本身被@Transactional或@Cacheable注解,Spring 会为其生成代理对象。此时直接通过new创建实例会失去代理能力,必须通过 Spring 容器获取策略实例。这正是策略上下文(Context)通过依赖注入管理策略实例的重要原因。

相关新闻

  • utsudo多架构支持:AMD64/ARM64/loongarch64部署最佳实践
  • 如何用League Akari打造你的英雄联盟终极自动化助手:完整指南
  • 计算机毕业设计之黄海学院毕业生管理系统

最新新闻

  • ICM-42688-P与PIC18F46K40在工业自动化中的高精度运动控制方案
  • 直流电机静音控制方案设计与实现
  • 完全掌握CTFAK 2.0:游戏资源提取的专业解析与效率革命
  • 如何快速掌握LangGraph:构建智能Agent的终极入门指南
  • 2026年实测10款降AIGC软件推荐:免费与付费全对比,毕业论文淡化AIGC痕迹必看
  • 小程序商城制作一个需要多少钱?从年费、功能和设计补充拆账

日新闻

  • JMeter接口测试实战:从核心元件到复杂场景构建
  • Java Applet版刽子手游戏源码:含完整项目结构、吊杆绘图与胜负逻辑
  • 使用Apache JMeter对RoadRunner PHP应用进行性能测试与调优指南

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号