从C++编程入手设计模式——策略设计模式

从C++编程入手设计模式——策略设计模式

​ 在我们平时写程序的过程中,经常会遇到这样的情况:一个对象的某个功能可以有多种实现方式,而且可能会根据不同的场景切换这些方式。比如一只动物可以发出不同的叫声,一个排序器可以使用不同的排序算法,一个支付系统可以接入不同的支付平台。这时候,我们就可以使用“策略设计模式”。

​ 策略策略,实际上就是做一个事情的策略方法。换而言之,这个设计模式用在哪些应付解决方案多变的场景。我们把某个行为(比如“怎么叫”“怎么排序”“怎么支付”)封装成一个独立的策略对象,让原本需要执行这个行为的类把这个行为委托给策略对象来完成。这样,我们可以很方便地替换行为、扩展行为,而不需要修改原来的类。

#include <iostream>
#include <functional>class Context {
public:void setStrategy(std::function<void()> strat) {strategy = strat;}void executeStrategy() {if (strategy) {strategy();}}private:std::function<void()> strategy;
};

​ 如你所见,这就是把我们具体的实现行为替换成给定接口的函数指针。

策略模式的结构

从设计的角度来看,策略模式通常包含三部分:

  1. 策略接口:定义某个行为的抽象,比如“排序算法”或“支付方式”。
  2. 具体策略:不同的实现,比如“冒泡排序”、“支付宝支付”。
  3. 上下文类:也就是使用这些策略的地方,内部持有一个策略接口的对象,通过它来执行行为。

什么场景适合用策略模式

  • 有多个算法可以选择,比如不同的排序方法、路径规划算法等。
  • 行为需要根据不同条件动态变化,比如不同平台上的绘图方式。
  • 不同业务场景下执行逻辑不同,比如不同国家的税率计算方式。

和 if-else 的区别在哪?

很多人会说:“我直接写一堆 if-elseswitch 不也可以吗?”确实可以,但这样做有两个问题:

  • 每增加一种新行为就要改动原来的代码,不利于维护。
  • 所有实现都混在一起,导致类越来越臃肿,不利于阅读和测试。

而使用策略模式,每个行为单独封装起来,不但代码更清晰,还能独立测试每一个策略实现。

一个例子

需求:设计一个动物模拟器,支持不同动物发出不同的叫声。使用策略模式实现动物叫声的可变换(例如狗叫 “汪汪”,猫叫 “喵喵”)。

要求

  • 定义 ISoundStrategy 接口,有一个 makeSound() 函数。
  • 实现 DogSoundStrategyCatSoundStrategy 等具体策略类。
  • 定义 Animal 类,持有一个 ISoundStrategy*
  • 允许运行时更换动物的叫声策略。

示例输出

Dog: 汪汪
Cat: 喵喵
Dog changes to cat sound: 喵喵

笔者没有严格的实现这个题目的要求,但是您可以参考一下:

modern-cpp-patterns-playground/Strategy/AnimalSound at main · Charliechen114514/modern-cpp-patterns-playground

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/909626.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/909626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网页中调用自定义字体可以通过 ‌CSS‌ 的 @font-face 规则实现

以下是详细方法&#xff1a; ‌1. 使用系统默认字体‌ 如果只是希望指定字体&#xff0c;可以直接使用 font-family&#xff1a; body { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; /* 中英文适配 */ } ‌2. 使用自定义字体&…

[CVPR 2025] DeformCL:基于可变形中心线的3D血管提取新范式

CVPR 2025 | DeformCL&#xff1a;基于可变形中心线的3D血管提取新范式 论文信息 标题&#xff1a;DeformCL: Learning Deformable Centerline Representation for Vessel Extraction in 3D Medical Image作者&#xff1a;Ziwei Zhao, Zhixing Zhang, Yuhang Liu, 等单位&…

BeckHoff <---> Keyence (LJ-X8000) 2D相机 Profinet 通讯

目录 ​编辑 一、 设备介绍 1、产品特点 2、控制器选择 3、应用领域 二、PLC通讯接口配置 1、PLC添加GSDML文件 2、定义输入3、变量实例化 3、定义输出变量实例化 三、设备通讯接口数据类型定义 1、定义全局结构体数据 2、定义 INput Decode结构体数据 四、通讯…

electron在单例中实现双击打开文件,并重复打开其他文件

单实例的思路 首次通过双击文件打开应用 将filePath传给render 使用中的应用&#xff0c;再次双击打开文件 第一个实例创建时&#xff0c;同时创建一个通信服务器net.createServer()第二个实例创建时&#xff0c;连接第一个服务器net.createConnection()将再次打开的filePath传…

一、基础架构层:高性能引擎基石

1. ECS架构工业级实现 // EnTT实战示例&#xff1a;导弹系统组件定义 struct Position { vec3 value; }; struct Velocity { vec3 value; }; struct ExplodeWhen { float distance; };entt::registry registry;// 实体创建与组件绑定 auto missile registry.create(); regist…

rockylinuxapache和Linux服务配置

目录 apache nginx 反向代理配置[rootk8s2 ~]# [rootk8s2 ~]# cat /etc/nginx/conf.d/webserver.confserver { listen 80; server_name www.sxy1.com; location / { root /var/www/html; index index.html; } location /py/{ …

ai 幻觉

ai幻觉: 感知人类观察者不存在或无法感知的模式或对象&#xff0c;从而产生无意义或完全不准确的输出 有时 AI 算法会生成并非基于训练数据的输出结果&#xff0c;继而被转换器错误解码或不遵循任何可识别的模式。换句话说&#xff0c;它会在给出响应时“产生幻觉” 致因:训练…

freeRTOS移植实验

提示&#xff1a;文章 文章目录 前言一、背景第6章节 二、2.12.2 三、3.1 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 在家里先使用野火网盘资料里的freeRTOS源码&#xff0c;网盘里是v9.0.0。 J:\野火\STM32F103ZET6_霸道开发板\A盘&#xff08;资料盘…

食品加工温控场景:PROFIBUS转MODBUS的温控表连接规范

在现代的工业自动化领域里&#xff0c;实现不同通信协议设备间无缝对接的技术日益受到重视。这不仅关乎系统整合性和效率的提升&#xff0c;更是实现复杂工业过程自动化的必经之路。特别是在众多的通信协议中&#xff0c;MODBUS和PROFIBUS这两种广泛使用的协议因其各自的优势而…

【动态规划】回文串(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的动态规划算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&…

Ubuntu22.04.5 桌面版然后安装 VMware 17

安装 VMware 需要 GCC 12版本 标题通过 PPA 安装 这是最简单的方法&#xff0c;适用于大多数 Ubuntu 版本。 步骤 1&#xff1a;添加 PPA 仓库 sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt…

深入解析 MySQL 架构:从基础到高级

MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff0c;以其高性能、可靠性和灵活性而闻名。无论是小型创业公司还是大型企业&#xff0c;MySQL 都是许多应用程序的首选数据库解决方案。本文将深入探讨 MySQL 的架构设计&#xff0c;帮助读者更好地理解其内部工作机制&am…

BACnet协议移植适配实现BACnet/IP和BACnet MSTP相关功能

1、从GitHub或者其他网站下载最新的协议栈源码 源码结构如图所示&#xff1a; 其中src是协议栈源码&#xff0c;可直接拿来使用&#xff0c;apps里面是一些功能的应用示例&#xff0c;有BACnet IP&#xff0c;BACnet MSTP&#xff0c;BACnet Router等功能。 2、协议栈移植完成…

Ubuntu 22.04.1 LTS 离线安装Docker(最快方法,仅需一个压缩文件和两个脚本)

作者亲测&#xff1a;亲测有效无bug。 利用ubuntu22.04下载完docker-27.4.1.tgz,然后按照下面方法安装。选择sudo方法。 tips:这个ubuntu22.04是迁移后的服务器的版本&#xff0c;不是迁移前的版本。 下载 下载地址 : https://download.docker.com/linux/static/stable/x86_…

Tkinter --按钮点击事件应用场景

第二章 事件处理 目录 第二章 事件处理 四、事件处理 4.1 按钮点击事件 4.1.1信息展示类场景 1. 静态文本说明 ​编辑 2. 动态状态显示 4.1.2.界面美化与装饰 1. 图像 / 图标展示 ​编辑 2. 分隔与布局辅助 4.1.3 交互反馈与提示 1. 操作结果提示 2. 帮助与说明文本…

计算机网络学习笔记:TCP流控、拥塞控制

文章目录 前言一、TCP流量控制1.1、案例&#xff1a;三次流量控制1.2、持续计时器 二、TCP拥塞控制2.1、拥塞控制的指标2.2、慢开始算法和拥塞避免算法2.3、快重传算法和快恢复算法2.4、练习 三、TCP拥塞控制与网际层拥塞控制总结 前言 TCP协议中的流量和拥塞&#xff0c;是两个…

【Linux】Tomcat搭建

前言 Tomcat Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。 JSP JSP是一种跨平台的动态网页技术标准&#xff0c;可以…

Ajax 核心知识点全面总结

文章目录 Ajax 核心知识点全面总结一、Ajax 基础概念1、定义2、核心特点 二、Ajax 工作原理与核心组件1、工作流程2、XMLHttpRequest&#xff08;XHR&#xff09;对象 三、Ajax 请求方法与参数1、常见请求方法2、请求参数处理 四、Ajax 异步与错误处理1、异步处理2、错误处理 五…

SpinFlowSim:用于癌症组织学信息驱动的扩散MRI微血管映射的血流模拟框架|文献速递-深度学习医疗AI最新文献

Title 题目 SpinFlowSim: A blood flow simulation framework for histology-informeddiffusion MRI microvasculature mapping in cancer SpinFlowSim&#xff1a;用于癌症组织学信息驱动的扩散MRI微血管映射的血流模拟框架 01 文献速递介绍 在扩散磁共振成像&#xff08…

量化面试绿皮书:21. 抛硬币游戏

文中内容仅限技术学习与代码实践参考&#xff0c;市场存在不确定性&#xff0c;技术分析需谨慎验证&#xff0c;不构成任何投资建议。 21. 抛硬币游戏 两个赌徒正在玩一个抛硬币游戏。 赌徒A有(n1)枚均匀硬币&#xff0c;赌徒B有n枚均匀硬币。 Q: 如果两人同时抛掷所有硬币&a…