设计模式——策略设计模式(行为型)

article/2025/7/25 11:33:27

摘要

策略设计模式是一种行为型设计模式,它定义了一系列算法并将每个算法封装起来,使它们可以相互替换。该模式让算法的变化独立于使用算法的客户,从而使得算法可以灵活地切换和扩展。其主要角色包括策略接口、具体策略类和环境类。策略模式的结构通过类图和时序图进行展示,实现方式涵盖定义策略接口、实现具体策略类、定义环境类等步骤。它适用于多种场景,如在Spring中动态选择策略等,同时也有其不适用的场景。实战示例包括需求背景、策略接口及实现类、策略上下文类等,有助于理解策略模式的实际应用。

1. 策略设计模式定义

策略设计模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法(策略),并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户,从而使得算法可以灵活地切换和扩展。

核心思想:将不同的算法封装成独立的策略类,客户端通过调用统一的接口来选择和执行具体的策略,而不用关心具体的实现细节。

1.1.1. 策略设计模式的主要角色:

  • 策略接口(Strategy):定义一系列算法的公共接口。
  • 具体策略类(ConcreteStrategy):实现策略接口的具体算法。
  • 环境类(Context):持有一个策略对象的引用,负责调用具体策略的方法。

2. 策略设计模式结构

策略模式包含如下角色:

  • Context: 环境类
  • Strategy: 抽象策略类
  • ConcreteStrategy: 具体策略类

2.1. 策略设计模式类图

2.2. 策略设计模式时序图

3. 策略设计模式实现方式

3.1. 定义策略接口(Strategy)

定义一个公共接口,声明所有具体策略类需要实现的方法。

public interface Strategy {void execute();
}

3.2. 实现具体策略类(ConcreteStrategy)

实现策略接口的多个具体类,分别封装不同的算法或行为。

@Component("strategyA")
public class ConcreteStrategyA implements Strategy {@Overridepublic void execute() {System.out.println("执行策略 A");}
}@Component("strategyB")
public class ConcreteStrategyB implements Strategy {@Overridepublic void execute() {System.out.println("执行策略 B");}
}

3.3. 定义环境类(Context)

环境类持有策略接口引用,通过调用接口的方法来执行具体策略。

@Component
public class StrategyContext {private Strategy strategy;// 通过setter注入当前使用的策略public void setStrategy(Strategy strategy) {this.strategy = strategy;}public void executeStrategy() {strategy.execute();}
}

3.4. 在Spring中动态选择策略

通过Spring容器自动注入所有策略类,利用策略名称或者业务标识动态选择执行的策略。

@Component
public class StrategyService {private final Map<String, Strategy> strategyMap;@Autowiredpublic StrategyService(Map<String, Strategy> strategyMap) {this.strategyMap = strategyMap;}public void execute(String strategyName) {Strategy strategy = strategyMap.get(strategyName);if (strategy == null) {throw new IllegalArgumentException("无效的策略名称:" + strategyName);}strategy.execute();}
}

3.5. 使用示例(调用)


@Autowired
private StrategyService strategyService;public void test() {strategyService.execute("strategyA");  // 执行策略AstrategyService.execute("strategyB");  // 执行策略B
}

3.6. 策略模式总结

  • 策略接口定义公共方法;
  • 具体策略类实现不同算法;
  • 环境类调用策略接口;
  • Spring容器管理策略类,通过注解和自动注入动态选择策略。

4. 策略设计模式适合场景

4.1. ✅ 适合使用策略设计模式的场景

场景

说明

多算法动态切换

系统中存在多种算法或行为,需要根据业务动态选择。

避免复杂条件判断

需要减少大量 if-else 或 switch-case 的代码。

算法封装与扩展

不同算法实现统一接口,方便互换和新增策略。

遵循单一职责原则

将变化的算法封装,保持代码清晰易维护。

支持新增策略不影响客户端

新策略可增加而无需修改客户端代码,符合开闭原则。

业务规则频繁变动

算法或业务规则经常调整,需灵活切换实现。

4.2. ❌ 不适合使用策略设计模式的场景

场景

原因

单一算法场景

只有一种算法,没有多策略选择,策略模式无意义。

算法简单且稳定

算法逻辑简单且变化不大,策略模式增加复杂度。

策略间依赖强

策略之间耦合较紧,无法独立替换。

频繁变更策略映射

频繁修改策略注册或映射,维护成本较高。

系统规模较小

设计复杂度不必要增加,适合直接调用简单实现。

5. 策略设计模式实战示例

5.1. 需求背景

假设风控系统中,有不同的风控策略(如:信用评分风控、黑名单风控、行为风控),业务根据不同场景动态选择策略执行风控校验。

5.2. 策略接口

public interface RiskControlStrategy {boolean checkRisk(String userId);
}

5.3. 具体策略实现类

import org.springframework.stereotype.Component;@Component("creditScoreStrategy")
public class CreditScoreStrategy implements RiskControlStrategy {@Overridepublic boolean checkRisk(String userId) {System.out.println("执行信用评分风控,用户:" + userId);// 伪代码:查询用户信用分,判断是否高风险return true;  // 通过}
}@Component("blacklistStrategy")
public class BlacklistStrategy implements RiskControlStrategy {@Overridepublic boolean checkRisk(String userId) {System.out.println("执行黑名单风控,用户:" + userId);// 伪代码:判断用户是否在黑名单中return false; // 拦截}
}@Component("behaviorStrategy")
public class BehaviorStrategy implements RiskControlStrategy {@Overridepublic boolean checkRisk(String userId) {System.out.println("执行行为风控,用户:" + userId);// 伪代码:分析用户行为风险return true;}
}

5.4. 策略上下文类(策略注册表)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Map;@Component
public class RiskControlStrategyContext {@Autowiredprivate Map<String, RiskControlStrategy> strategyMap;public RiskControlStrategy getStrategy(String strategyType) {return strategyMap.getOrDefault(strategyType, strategyMap.get("creditScoreStrategy"));}
}

5.5. 业务调用示例(例如 Controller 或 Service)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class RiskControlService {@Autowiredprivate RiskControlStrategyContext strategyContext;public boolean executeRiskCheck(String userId, String strategyType) {RiskControlStrategy strategy = strategyContext.getStrategy(strategyType);return strategy.checkRisk(userId);}
}

5.6. 策略模式使用示例

// 比如Controller层调用
@Autowired
private RiskControlService riskControlService;public void handleRequest(String userId, String riskType) {boolean passed = riskControlService.executeRiskCheck(userId, riskType);if (passed) {System.out.println("风控通过");} else {System.out.println("风控拦截");}
}

5.7. 总结

  • 各策略实现了统一接口,方便动态切换。
  • Spring容器自动扫描并注入所有策略,实现“策略注册表”。
  • 业务只需调用策略上下文类,无需关心具体策略实现。
  • 支持轻松扩展,新增策略只需新增实现并标注组件注解即可。

6. 策略设计模式思考

6.1. 哪些设计模式与策略模式常用与实战开发中?

策略设计模式常常和其他设计模式组合使用,以实现更加灵活、解耦且可扩展的系统设计。下面列出几个策略模式常见的组合模式及其实战意义

组合模式

作用和实战意义

工厂模式(Factory)

工厂模式负责策略对象的创建,结合策略模式实现动态策略实例化,避免客户端直接依赖具体策略类。

策略+工厂

通过工厂动态创建或获取策略实例,简化策略管理,便于新增策略。

策略+责任链模式

多个策略按责任链顺序依次执行,适合风控流程中多步校验和规则链式处理。

策略+装饰器模式

在策略的基础上动态添加额外行为(如日志、缓存、权限控制),增强策略功能。

策略+模板方法模式

模板方法定义固定流程,策略负责具体步骤的算法实现,二者分工清晰,灵活替换。

策略+桥接模式

桥接模式分离策略接口与实现,策略作为抽象层一部分,便于独立扩展和变化。

策略+命令模式

命令模式封装请求,策略定义请求的处理算法,便于请求调用与执行分离。

策略+观察者模式

观察者模式监听策略执行结果,实现事件驱动的策略调整和联动处理。

策略+代理模式

代理在调用策略前后添加横切逻辑,如权限检查、性能统计。

策略+状态模式

状态模式控制状态切换,策略定义每状态下的具体行为。

简单示例说明

  • 策略 + 工厂:风控策略的工厂负责创建或注入具体策略,客户端通过工厂获取策略实例。
  • 策略 + 责任链:风控中,多个风控策略组成责任链,一个接一个执行直到拦截或全部通过。
  • 策略 + 装饰器:对某个策略加日志功能或缓存功能,用装饰器包装策略实例。

博文参考

  • 5. 策略模式 — Graphic Design Patterns
  • 策略设计模式

http://www.hkcw.cn/article/foXWDdQnYA.shtml

相关文章

女子用高压锅煮粽子不慎炸穿天花板 厨房安全引重视

5月28日,浙江杭州一女子用高压锅煮粽子时引发爆炸,厨房一片狼藉。糯米溅了满墙,天花板还被炸出一个大洞。这类事故并不少见。高压锅通常配备泄压阀,如果排气孔被堵住,锅内压力无法释放,就可能引发爆炸。端午节临近,大家在使用高压锅时务必注意安全,确保平安享用美食。责…

微软更新Win11最低系统要求页面,明确Copilot+ PC配置需求 新增处理器和内存要求

今年3月,微软更新了Windows 11的最低系统要求页面,旨在帮助用户更好地选购支持Copilot+ PC的电脑。微软推荐用户购买新的系统,尤其是Copilot+ AI PC,以获得最佳的Windows使用体验。微软推出的Copilot+ PC系列专注于处理人工智能任务。Windows 11 24H2版本中包含了许多人工智…

美国载有2.5亿只蜜蜂卡车翻车,靠近加拿大 养蜂专家紧急救援

美国华盛顿州近日发生了一起罕见事故,一辆载有约2.5亿只蜜蜂的半挂卡车在行驶途中翻覆,导致大量蜜蜂倾巢而出。事发地点靠近加拿大边境,距离温哥华仅约48公里。当地警方迅速封锁道路,并呼吁民众远离蜂群,同时紧急召集养蜂专家到场协助“收蜂”。怀特康郡警局发布公告称,事…

[创业之路-400]:企业战略管理案例分析-战略规划-创新焦点

一、战略规划中的创新焦点&#xff1a;核心概念与实施路径 1.1、创新焦点的核心定义 创新焦点是战略规划中明确企业未来创新方向的关键环节&#xff0c;其核心在于&#xff1a; 用户需求驱动&#xff1a;以解决用户痛点或创造新价值为核心&#xff1b;差异化竞争&#xff1a…

美媒曝台湾地区有500名美军人员 人数激增引发关注

据美国军方媒体《星条旗报》报道,已退役的美国海军少将马克蒙哥马利近日在美国国会声称,大约有500名美军人员在中国台湾地区活动,这一数字远超此前美国国会披露的41人。蒙哥马利在5月15日出席美国国会众议院“中国问题特别委员会”的听证会时宣称,目前有约500名美军人员在台…

小莫连用三个really回应樊振东加盟 乒坛巨星携手引期待

近日,乒坛传来重磅消息。北京时间6月1日,德国乒乓球甲级联赛球队FC萨尔布吕肯官方宣布,奥运冠军樊振东将加盟球队,参加2025-2026赛季的德甲联赛和欧洲冠军联赛。同一天,萨尔布吕肯俱乐部在欧洲乒乓球冠军联赛男团决赛中第三次夺得欧冠冠军,莫雷加德凭借出色表现被评为赛事…

律师解读男子遭精神病邻居砸门咒骂 法律与权益保护解析

吉林松原的刁先生自2022年12月以来,一家人长期受到楼下精神病邻居上门砸门咒骂,生活严重受到影响,除了做饭外几乎只能待在阁楼生活。根据相关文件显示,违法行为人系精神病人,案发时处于妄想状态,不予行政处罚。因其儿子不同意送医治疗,且未有刑事案件发生,警方和政府不…

A股上市公司名单一览 芜湖市达21家

5月29日,安徽古麒绒材股份有限公司在深交所主板上市。至此,芜湖市A股上市公司总数达到21家,在安徽省内排名第二。以下是芜湖市A股上市公司的具体名单:A股主板公司有: - 海螺新材 (000619.SZ) - 中公教育 (002607.SZ) - 丰原药业 (000153.SZ) - 鑫科材料 (600255.SH) - 海螺…

《碟中谍8》:血肉之躯的终极献祭 极限特技再创高峰

美国派拉蒙影片公司出品的经典特工系列新作《碟中谍8:最终清算》今日发布了“信仰之跃”幕后特辑。特辑以第一视角展示了汤姆克鲁斯从海拔千米高空自由落体的惊险拍摄现场,全程无替身无绿幕,观众能直接感受到大风呼啸和天旋地转的刺激。首映后,观众对影片赞誉有加,称赞其扣…

“以旧换新”带货1万亿,中国何时能步入“消费者社会”? 从生产者到消费者转型

美国试图让制造业回流,成为一个踏实劳作的“生产者社会”,而中国则努力扩大消费,成为一个繁荣向上的“消费者社会”。特朗普在宾夕法尼亚州匹兹堡附近的一家新成立的钢铁公司召开集会,宣布将进口钢铁和铝的关税从25%提高至50%,以保护美国工人的饭碗。匹兹堡曾是美国著名的…

我国多地将有8级以上雷暴大风天气 强对流预警持续

中央气象台6月2日06时继续发布暴雨蓝色预警和强对流天气蓝色预警。预计6月2日08时至3日08时,福建东部和南部沿海、广东中南部、广西南部、云南西北部和东部、西藏东南部以及黑龙江西部等地部分地区有大到暴雨,其中广东中部局地有大暴雨(100~140毫米)。上述地区伴有短时强降…

萨巴伦卡回应将对阵郑钦文 誓言复仇之战

6月2日凌晨,萨巴伦卡以2-0战胜了阿尼西莫娃,顺利进入法网女单8强。在接下来的1/4决赛中,她将与郑钦文再次交手,对于这场比赛,萨巴伦卡充满了复仇的欲望。作为目前的世界第一,萨巴伦卡是本赛季女子网坛表现最出色的球员之一。此次参加法网,她的状态依旧火热,前四轮比赛中…

举办中国头盔护具展哪个城市较理想

有着强劲经济引擎杭州&#xff0c;中国头盔护具展举办地较理想之选&#xff01; 为什么是杭州&#xff1f;—— 硬核实力&#xff01; -经济活力领跑&#xff1a; 浙江人均GDP超2.5万美元&#xff0c;人均收入与消费全国TOP 1&#xff01;2024年省外人口净流入45.4万&#xff…

包管理后续部分

pnpm做了什么 当你使用npm或者Yarn的时候&#xff0c;如果你有100个项目&#xff0c;并且所有项目都有一个相同的依赖包&#xff0c;那么在硬盘上就需要保存100份该相同依赖包的脚本 如果使用pnpm&#xff0c;依赖包就将被存放在一个统一的位置 所以&#xff1a; 如果对同一…

长江-1000A能否当“救火队长” 国产航发迎挑战

就在不久前,中国商飞宣布将今年产能从50架提升到75架。随后,美国商务部暂停向中国商飞发放多项技术许可证,其中包括C919所用的LEAP-1C发动机。这实际上是特朗普政府直接下令对C919发动机断供。随着C919产量提升,逐步对波音构成威胁,美国的断供并不令人意外。关键在于国产航…

荣昌龙舟比赛 卤鹅哥当鼓手划龙舟 桨影翻飞竞速激

5月31日至6月2日,“千年荣昌龙舟争渡”端午龙舟赛在荣昌区濑溪河礼悦东方段—联升桥河段举行。来自荣昌本土的16支队伍参与了200米和500米直道竞速赛,濑溪河上再现龙舟竞渡、桨影翻飞的热闹场景。6月1日,随着开赛鸣笛声响起,龙舟如离弦之箭在濑溪河上竞相逐浪。选手们伴随着…

同样人生坎坷,“前辈”金文洙能否打败李在明“逆风翻盘”?

▲当地时间2025年6月1日,韩国国民力量党总统候选人金文洙在竞选活动中发表讲话。图据视觉中国2025年4月,前总统尹锡悦被弹劾下台,韩国进入总统大选时间。最大在野党共同民主党的强劲势头,加上尹锡悦带来的负面影响,执政党国民力量党遭受巨大冲击。在这样的背景下,曾在尹锡…

Python中的机器学习:从线性回归到随机森林的实现

Python中的机器学习&#xff1a;从线性回归到随机森林的实现 机器学习是现代科技的核心驱动力之一&#xff0c;它通过让计算机从数据中学习&#xff0c;从而实现自主决策和预测。在Python中&#xff0c;机器学习的实现不仅高效&#xff0c;而且极其灵活&#xff0c;从简单的线…

【IC】低功耗IC设计:技术和最佳实践

低功耗IC&#xff08;集成电路&#xff09;设计是现代电子产品的关键要素&#xff0c;因为它可以延长电池寿命并降低设备的能耗。电池供电设备市场的不断增长&#xff0c;使得芯片设计人员必须认真考虑各种降低IC功耗的技术。目前有多种技术可用于降低IC的静态和动态功耗。静态…

C++11新特性包装器

目录 1.function 2。 150. 逆波兰表达式求值 ​编辑 1.function C11中提供了新的类模板function&#xff0c;它是一个包装器&#xff0c;可以包装其它可以存储调用其它的可调用对象&#xff0c;这里的可调用对象包括函数指针&#xff0c;仿函数&#xff0c;.lambda,bind表达…