当前位置: 首页 > news >正文

设计模式实战篇(二):业务逻辑“随时切换招式”——策略模式(Strategy Pattern)解析

是否正苦恼于一堆 if/else 引发的代码灾难?
想让算法像“武功招式”一样可随时切换?
策略模式就像“可拔插的算法模块”,让你的代码像积木一样灵活。
策略模式就是专为这种“行为可替换”场景而设计的。


一、什么是策略模式?一句话讲透它的思想

策略模式是这样一种设计理念:

将一组可替代的算法独立封装,使调用者无需关注具体实现,并允许在运行时自由切换策略。

你可以把策略看成游戏中的“技能卡”:

  • 想打爆发,换“暴击卡”
  • 想续航,换“回血卡”
  • 想加速,换“疾风卡”

同样,在业务里也一样灵活。


⚙️ 二、策略模式适用的典型业务场景

业务领域可切换的策略示例说明
支付方式支付宝、微信、银联新增支付方式不影响旧代码
优惠算法满减、折扣、积分换算电商强需求
排序方案时间、评分、热度排序算法替换频繁
日志输出本地、Kafka、ES运维系统常见
推荐系统个性化、人气、新品推荐算法可插拔

你会发现几乎所有“可替换业务逻辑”的地方都能用策略模式。


🧩 三、策略模式流程图

设置策略
客户端 Client
Context 上下文
Strategy
策略接口
具体策略 A
具体策略 B

🧱 四、策略模式 UML 类图

«interface»
Strategy
+execute(double amount)
AliPayStrategy
+execute(double amount)
WechatPayStrategy
+execute(double amount)
CreditCardStrategy
+execute(double amount)
PaymentContext
-Strategy strategy
+setStrategy(Strategy strategy)
+pay(double amount)

🔄 五、策略模式时序图

UserContextStrategysetStrategy()pay(amount)execute(amount)返回结果UserContextStrategy

💻 六、策略模式 Java 实战:支付系统示例

1)策略接口

public interface PayStrategy {void pay(double amount);
}

2)具体策略实现

public class AliPayStrategy implements PayStrategy {@Overridepublic void pay(double amount) {System.out.println("使用支付宝支付:" + amount + " 元");}
}public class WechatPayStrategy implements PayStrategy {@Overridepublic void pay(double amount) {System.out.println("使用微信支付:" + amount + " 元");}
}public class CreditCardStrategy implements PayStrategy {@Overridepublic void pay(double amount) {System.out.println("使用信用卡支付:" + amount + " 元");}
}

3)Context(策略上下文)

public class PayContext {private PayStrategy strategy;public void setStrategy(PayStrategy strategy) {this.strategy = strategy;}public void pay(double amount) {strategy.pay(amount);}
}

4)客户端调用

public class Main {public static void main(String[] args) {PayContext context = new PayContext();context.setStrategy(new AliPayStrategy());context.pay(100);context.setStrategy(new WechatPayStrategy());context.pay(200);context.setStrategy(new CreditCardStrategy());context.pay(300);}
}

🚀 七、策略模式优势

特性策略模式带来的能力
开闭原则新策略无需改老代码
解耦行为独立封装
插件化可以动态组合策略
可测试性每个策略单测方便
避免 if/else大幅提高可读性

如果你在项目中发现大量 if/else + 业务选择逻辑,大概率就是策略模式缺位了。


🧠 八、策略模式常见误区(反模式警示)

在实际项目中,很多开发者以为自己用了策略模式,但其实出现了以下“伪策略模式”问题:

❌ 误区一:策略内部出现 if/else 再分支

示例:

public class AliPayStrategy implements PayStrategy {public void pay(double amount) {if (isFastMode) { ... }else if (isSafeMode) { ... }}
}

这是典型的“策略里再塞策略”,说明设计层级不清晰。

✔ 正确做法:
把内部行为继续分层,用“策略 + 工厂”组合拆分。

❌ 误区二:Context 写死策略创建逻辑

public PayContext() {this.strategy = new AliPayStrategy();
}

这会让策略模式失去意义。

✔ 正确做法:
策略必须由外部注入,才能实现开闭原则。

❌ 误区三:策略太多、难以维护

当策略数量超过 20 个时,需要考虑:

  • 把策略分包管理
  • 考虑用枚举 + 工厂帮助组织
  • 引入策略标签提升可读性
  • 若策略本质是业务可配置逻辑 → 用“规则引擎”替代策略模式(如 drools)

🔍 九、策略模式与其他设计模式的对比(非常容易混淆)

模式与策略模式的区别
模板方法(Template Method)父类定义流程,子类填步骤。策略模式是完全独立的算法替换。
状态模式(State)策略 = 动态切换行为;状态 = 动态切换对象状态,并影响下一个状态路径。
简单工厂工厂解决“创建”;策略解决“行为替换”。
责任链模式策略只执行一个算法;责任链可以串多个算法。

一句话记忆:

模板方法是结构化流程;策略模式是横向替换算法;责任链模式是组合算法流程。


🏢 十、策略模式在企业级项目中的典型落地方式

1)在支付系统中

  • 新增支付方式无需改旧代码
  • 每个支付渠道对应独立策略
  • 策略 + 工厂结合使用,与渠道编码映射

2)优惠模块(电商核心)

  • 满减、满折、N 件 X 元
  • 不同店铺可配置不同策略
  • 支持按配置动态装配策略链(策略 + 责任链混合)

3)机器学习/推荐系统

  • 替换排序算法
  • 替换召回模型
  • 替换归一化方法

策略模式让算法像插件一样“热插拔”。


🌱 十一、Spring 中的策略模式使用示例(非常实用)

Spring 对策略模式有天然支持。

方式一: 使用 @Autowired Map<String, Strategy>

@Autowired
private Map<String, PayStrategy> strategies;

Spring 会自动把所有实现该接口的 bean 装入 map,key 为 beanName。

strategies.get("aliPayStrategy").pay(100);

超级适合做“策略路由”。

方式二: 使用 @Qualifier 指定策略

@Autowired
@Qualifier("wechatPayStrategy")
private PayStrategy strategy;

方式三: 使用注解自动关联策略

自定义注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PayChannel {String value();
}

每个策略上使用:

@PayChannel("ALI")
public class AliPayStrategy implements PayStrategy {...}

启动扫描自动注册到策略池,非常企业级玩法。


⚡ 十二、策略模式自动注册 + 工厂增强版(高级示例)

1)策略工厂

public class StrategyFactory {private static final Map<String, PayStrategy> STRATEGY_MAP = new HashMap<>();public static void register(String key, PayStrategy strategy) {STRATEGY_MAP.put(key, strategy);}public static PayStrategy get(String key) {return STRATEGY_MAP.get(key);}
}

2)策略自动注册

public abstract class AbstractPayStrategy implements PayStrategy {protected AbstractPayStrategy(String key) {StrategyFactory.register(key, this);}
}

3)策略实现

public class AliPayStrategy extends AbstractPayStrategy {public AliPayStrategy() {super("ALI");}@Overridepublic void pay(double amount) {System.out.println("支付宝支付:" + amount);}
}

客户端即可:

StrategyFactory.get("ALI").pay(99.9);

真正做到 零侵入可扩展插件化

http://www.dtcms.com/a/609139.html

相关文章:

  • 从“能说会道”到“自主思考”:一文读懂AI的过去、现在与未来
  • Python语言编译器 | Python语言编译器的使用与原理解析
  • 【JAVA 进阶】Spring Boot 注解体系与工程实践
  • Effective Python 第51条:优先考虑通过类修饰器来提供可组合的扩充功能,不要使用元类
  • Rust时序数据库实现:从压缩算法到并发优化的实战之旅
  • SpringCloud-Consul服务注册与发现
  • 网站建设原因分析wordpress 页面分页
  • SSH级知识管理:通过CPolar暴露Obsidian vault构建你的知识API服务,实现跨设备无缝同步
  • 《Linux系统编程之进程基础》【进程入门】
  • Hello-agents TASK03 第四章节 智能体经典范式构建
  • C++ 二叉搜索树(BST)完全指南:从概念原理、核心操作到底层实现
  • 电子电气架构 --- 哨兵模式初入门
  • 桌面开发,在线%考试管理%系统,基于eclipse,java,swing,mysql数据库。
  • 超融合架构的核心组件与协同机制深度解析
  • 桌面开发,在线%图书管理%系统,基于eclipse,jdk,java,swing,sqlserver数据库
  • 快速学会做网站网站建设公司怎么推广
  • 无需 iTunes 备份与恢复 iPhone 的 2 种方法
  • 【Linux】Ubuntu图形界面崩溃(无法进入)的解决方法汇总
  • Lidar调试记录Ⅳ之Ubuntu22.04+ROS2+Livox_SDK2环境下编译Livox ROS Driver 2
  • 网站收录查询网摘抄一则新闻
  • 做电影网站违法么深圳网站建设10强
  • 荆州北京网站建设如何自己做网页链接
  • 网站建设开发教程视频网站如何建设目录
  • 为企业为什么做网站数据分析师是干嘛的
  • 叶县建设局网站网站快速建设视频
  • 保定 网站制作门户网站如何建设
  • 网站建设基本流程视频网站建站思路
  • 三星官网网站wordpress评论钩子
  • 关于网站开发的外文书籍怎么做网站软件
  • 好一点的网站建设电商代运营公司