设计模式-Strategy 模式(策略)

news/2025/2/25 9:05:17/

解释

Strategy 模式和 Template 模式要解决的问题是相同(类似)的,都是为了给业务逻辑(算法)具体实现和抽象接口之间的解耦。Strategy 模式将逻辑(算法)封装到一个类(Context)里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现。

应用场景示例:

数据导出格式选择假设需要实现一个数据导出工具,支持多种格式(CSV、XML、JSON)。若不用策略模式,会在导出逻辑中频繁出现条件分支,导致代码臃肿且难以扩展。

不使用策略模式的问题代码

class DataExporter {
public:void exportData(const std::string& format) {if (format == "CSV") {// CSV导出逻辑(约20行代码)std::cout << "Exporting data as CSV..." << std::endl;} else if (format == "XML") {// XML导出逻辑(约30行代码)std::cout << "Exporting data as XML..." << std::endl;} else if (format == "JSON") {// JSON导出逻辑(约25行代码)std::cout << "Exporting data as JSON..." << std::endl;}// 每新增一个格式都要修改此处}
};

使用策略模式的解决方案

// 策略接口
class ExportStrategy {
public:virtual ~ExportStrategy() = default;virtual void executeExport() = 0;
};// 具体策略
class CsvExport : public ExportStrategy {
public:void executeExport() override {std::cout << "Exporting data as CSV..." << std::endl;}
};class XmlExport : public ExportStrategy {
public:void executeExport() override {std::cout << "Exporting data as XML..." << std::endl;}
};class JsonExport : public ExportStrategy {
public:void executeExport() override {std::cout << "Exporting data as JSON..." << std::endl;}
};// 上下文类
class ExportContext {
private:ExportStrategy* strategy_;
public:void setStrategy(ExportStrategy* strategy) {strategy_ = strategy;}void performExport() {if (strategy_) {strategy_->executeExport();} else {std::cout << "No export strategy selected!" << std::endl;}}
};

关键对比分析

维度策略模式使用策略模式
扩展性新增格式需修改原有类只需新增策略类,符合开闭原则
可维护性200行巨型方法难维护每个策略独立维护(20-30行/类)
测试难度需覆盖所有条件分支可单独测试每个策略
代码复用相似逻辑无法复用可跨项目复用导出策略
运行时灵活性需重启修改代码动态切换导出策略(如根据配置文件)

典型应用场景

  1. 文件压缩工具:支持ZIP/RAR/7Z等算法
  2. 导航系统:实时切换最短路径/避开收费/避开高速等路线策略
  3. 游戏AI:不同难度级别的敌人行为策略
  4. 数据校验:多种校验规则(邮箱/手机号/身份证)的动态切换

何时不建议使用?

  • 策略数量极少(<3种)且确定不会扩展
  • 策略之间存在大量共享状态导致解耦困难
  • 算法需要访问对象内部私有状态(可能破坏封装)

通过这种设计,系统核心复杂度从O(n)(每次新增策略都要修改核心类)降为O(1),特别适合需要频繁扩展业务场景的中间件系统或框架设计。


http://www.ppmy.cn/news/1574812.html

相关文章

网络安全中的ac指什么

防火墙相关知识总结 防火墙介绍 防火墙工作层次部署模式 传统防火墙 1.包过滤防火墙2.状态检测防火墙3.应用代理防火墙ALG技术 防火墙介绍 定义&#xff1a;是一个把网络分成多个区域&#xff0c;不同区域定义不同安全级别&#xff0c;并默认阻止低安全级别区域访问高安全…

小迪安全-24天-文件管理,显示上传,黑白名单,访问控制

上节课回顾&#xff0c;token问题 没有更新token值&#xff0c;造成了复用 加上这段代码就好了&#xff0c;就不会复用了 文件管理-文件上传 upload.html文件&#xff0c;找ai生成就行 uoload.php接受文件上传的信息 这里在写个临时文件存储换个地方 因为上面临时文件存在c盘…

Linux系统网络配置与Bond多网卡绑定

目录 一、查看网络配置命令 1.1、ifconfig 1.2、ip 1.3、hostname 1.4、route 1.5、netstat 1.6、ss 1.7、ping 1.8、traceroute 1.9、nslookup 二、永久修改网络配置 2.1、网络接口配置文件 3.1、主机名配置文件 三、Bonding多网卡绑定 3.1、bondding工作模式 …

快速提升网站收录:利用网站评论互动

利用网站评论互动是快速提升网站收录的一种有效方法。以下是一些关于如何利用网站评论互动来提升网站收录的具体策略&#xff1a; 一、鼓励用户参与评论互动 设置评论区&#xff1a;在网站的相关页面&#xff0c;如文章页、产品页等&#xff0c;设置评论区&#xff0c;方便用…

算法日常刷题笔记(2)

为保持刷题的习惯 计划一天刷3-5题 然后一周总计汇总一下 这是第二篇笔记 笔记时间为2月17日到2月23日 第一天 找到初始输入字符串 找到初始输入字符串 Ihttps://leetcode.cn/problems/find-the-original-typed-string-i/ Alice 正在她的电脑上输入一个字符串。但是她打字技…

一周学会Flask3 Python Web开发-flask3上下文全局变量session,g和current_app

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili flask3提供了session,g和current_app上下文全局变量来方便我们操作访问数据。 以下是一个表格&#xff0c;用于比较Flask中的…

大语言模型(LLM)微调技术笔记

图1&#xff1a;大模型进化树2 大模型微调 在预训练后&#xff0c;大模型可以获得解决各种任务的通用能力。然而&#xff0c;越来越多的研究表明&#xff0c;大语言模型的能力可以根据特定目标进一步调整。 这就是微调技术&#xff0c;目前主要有两种微调大模型的方法1&…

【LeetCode 热题100】48. 旋转图像以及旋转任意角度的算法思路及python代码

48. 旋转图像 给定一个 n n n n nn 的二维矩阵 m a t r i x matrix matrix 表示一个图像。请你将图像顺时针旋转 90 90 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&…