【C++设计模式之命令模式:行为型】分析及示例
简介
命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使不同的请求可以被参数化、队列化或记录化。这种模式允许请求的发送者和接收者进行解耦,同时提供更高的灵活性和可扩展性。
描述
命令模式的核心思想是通过命令对象来封装请求。命令对象包含了执行请求的接收者和相应的动作。客户端通过将命令对象传递给调用者来触发请求的执行。
原理
命令模式包含以下几个关键角色:
- Command(命令):定义了命令的接口,声明了执行命令的方法。
- ConcreteCommand(具体命令):实现了Command接口,持有接收者对象,并实现具体的命令操作。
- Receiver(接收者):负责执行具体命令的对象。
- Invoker(调用者):有命令对象,调用命令来执行请求。
类图
其中,Invoker是调用者角色,要求该命令执行这个请求;
Command是命令角色,需要执行的所有命令都在这里声明,可以是接口或抽象类;
Receiver是接收者角色,知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者;
ConcreteCommand将一个接收者对象绑定与一个动作,调用接收者相应的操作,以实现Execute。
示例
假设有一个遥控器类 RemoteControl,可以通过按下不同的按钮来执行不同的操作,比如打开电视、关闭电视、调高音量等。我们可以使用命令模式来实现该遥控器:
#include <iostream>// Command(命令)
class Command {
public:virtual void execute() = 0;
};// Receiver(接收者)
class TV {
public:void turnOn() {std::cout << "电视已打开" << std::endl;}void turnOff() {std::cout << "电视已关闭" << std::endl;}void adjustVolume(int volume) {std::cout << "音量已调整为:" << volume << std::endl;}
};// ConcreteCommand(具体命令)
class TurnOnCommand : public Command {
private:TV* tv;
public:TurnOnCommand(TV* tv) : tv(tv) {}void execute() {tv->turnOn();}
};class TurnOffCommand : public Command {
private:TV* tv;
public:TurnOffCommand(TV* tv) : tv(tv) {}void execute() {tv->turnOff();}
};class AdjustVolumeCommand : public Command {
private:TV* tv;int volume;
public:AdjustVolumeCommand(TV* tv, int volume) : tv(tv), volume(volume) {}void execute() {tv->adjustVolume(volume);}
};// Invoker(调用者)
class RemoteControl {
private:Command* command;
public:void setCommand(Command* command) {this->command = command;}void pressButton() {command->execute();}
};int main() {// 创建遥控器和电视对象RemoteControl remoteControl;TV tv;// 创建具体命令对象Command* turnOnCommand = new TurnOnCommand(&tv);Command* turnOffCommand = new TurnOffCommand(&tv);Command* adjustVolumeCommand new AdjustVolumeCommand(&tv 10);// 设置具体命令到遥控器remoteControl.setCommand(turnOnCommand);remoteControl.pressButton(); // 打开电视remoteControl.setCommand(adjustVolumeCommand);remoteControl.pressButton(); // 调高音量remoteControl.setCommand(turnOffCommand);remoteControl.pressButton(); // 关闭电视// 释放资源delete turnOnCommand;delete turnOffCommand;delete adjustVolumeCommand;return 0;
}
输出结果
电视已打开
量已调整为:10
电视已关闭
解释
在上面的示例中,遥控器类 RemoteControl 充当调用者角色,持有命令对象并调用命令的 execute() 方法。具体命令类 TurnOnCommand、TurnOffCommand 和 AdjustVolumeCommand 分别对应打开电视、关闭电视和调整音量这三个具体的命令操作。它们实现了 Command 接口,并在执行 execute() 方法时调用接收者 TV 的相应方法。
结论
命令模式将请求和执行分离开来,提供了一种松耦合的方式,使得请求发送者和接收者可以方便地扩展和变化。同时,命令模式也可以对请求进行队列化、记录化等操作,增加系统的灵活性和可扩展性。
应用场景
- 需要将具体命令与调用者解耦,使得两者间不直接依赖的情况。
- 需要对请求进行排队、记录操作历史等场景。
- 需要支持撤销、重做等功能时。
上述示例实现了一个遥控器控制电视的功能,可以对电视执行打开、关闭和调整音量等操作。通过命令模式,遥控器和具体命令之间实现了解耦,可以很方便地扩展新的命令或修改命令的实现方式。
相关文章:

【C++设计模式之命令模式:行为型】分析及示例
简介 命令模式是一种行为型设计模式,它将请求封装成一个对象,从而使不同的请求可以被参数化、队列化或记录化。这种模式允许请求的发送者和接收者进行解耦,同时提供更高的灵活性和可扩展性。 描述 命令模式的核心思想是通过命令对象来封装…...

二、Excel VBA 简单使用
Excel VBA 从入门到出门一、Excel VBA 是个啥?二、Excel VBA 简单使用 👋Excel VBA 简单使用 ⚽️1. 如何在Excel中手动编写VBA代码⚽️2. 如何在 Excel 中运行 VBA 代码⚽️3. 如何在Excel中记录VBA代码⚽️4. 如何在Excel中编辑录制的VBA代码⚽️5. 如…...
获取url后面的参数
方式一 final String queryString request.getQueryString(); System.out.println(queryString); //解码 System.out.println(URLDecoder.decode(queryString, StandardCharsets.UTF_8));测试: pageSize25&pageNum1&sort%5B%27id%27%5Ddesc&sort%5B%…...

python入门篇07-数据容器(序列 集合 字典,json初识)基础(下)
全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 上文传送门 2. python基础使用2.1 序列2.1.1 序列定义2.1.2 序列参数解释2.1.3 列表list切片2.1.4 元组tuple切片2.1.5 字符串str切片 2.2 集合定义2.2.1 set集合-基本语法2.2.2 set集合-添加元素.add()2.2.3 set集合- 移除元…...

阿里云服务器公网带宽价格表“按固定带宽”计费模式
阿里云服务器公网带宽计费模式按固定带宽”计费多少钱1M?地域不同带宽价格不同,北京、杭州、深圳等大陆地域价格是23元/Mbps每月,中国香港1M带宽价格是30元一个月,美国硅谷是30元一个月,日本东京1M带宽是25元一个月&am…...
MTK的充电方案—PMIC充电
MTK目前有三套充电方案,主要如下: (1)线性充电——linering charge(PMIC充电) 充9停1,充电电流不能太大,目前最大能做到1.2A; (2)switch charge(…...

【Overload游戏引擎分析】画场景栅格的Shader分析
Overload引擎地址: GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后,场景视图中有栅格线,这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现࿰…...

智能化物流管理:全国快递物流查询API的角色与优势
前言 当今社会,物流行业已经成为了国民经济的重要组成部分,而快递物流则是物流行业中的一个重要分支。随着信息技术的不断发展,智能化物流管理正逐渐成为快递物流领域的趋势,而全国快递物流查询API作为其中的一部分,在…...

Spring Boot如何配置CORS支持
Spring Boot如何配置CORS支持 CORS(跨源资源共享)是一种Web浏览器的安全性功能,用于控制网页上的脚本文件从不同的源加载其他网页资源。在开发现代Web应用程序时,通常需要跨域请求不同的资源,如API服务或其他Web应用程…...

Mybatis 拦截器(Mybatis插件原理)
Mybatis为我们提供了拦截器机制用于插件的开发,使用拦截器可以无侵入的开发Mybatis插件,Mybatis允许我们在SQL执行的过程中进行拦截,提供了以下可供拦截的接口: Executor:执行器ParameterHandler:参数处理…...

AXI总线协议基础--几分钟熟悉通道信号和基础架构
目录 一、AXI协议基础 1.1读写通道的基本架构图 1.2猝发操作举例 1.3传输顺序 二、各个通道中的信号描述 2.1全局信号 2.2写地址通道信号 2.3写数据通道信号 2.4写响应通道信号 2.5读地址通道信号 2.6读数据通道 三、通道握手 3.1单一信息传输时的握手过程 3.2不…...

matlab数学建模方法与实践 笔记汇总
matlab数学建模方法与实践 笔记汇总 写在最前面笔记1:快速入门1.导入数据2.数据探索3.多项式拟合4.发布功能5.数据类型6、全部代码 笔记2:数据的准备1.数据的读取与写入excel、txt读图读视频 2.数据预处理缺失值噪声过滤数据归约数据变换 3.数据统计4.数…...

[UE虚幻引擎] DTCopyFile 插件说明 – 使用蓝图拷贝复制文件 (Windows)
本插件可以在虚幻引擎中使用蓝图对系统的其他文件进行拷贝复制操作。 1. 节点说明 Async Copy File 异步复制文件 Param Source File : 要复制的源文件的完整路径。Param Target File : 要复制的目标文件的完整路径。Param Force Copy : 如果为true,则如果目标…...

如何用ChatGPT学或教英文?5个使用ChatGPT的应用场景!
原文:百度安全验证 AI工具ChatGPT的出现大幅改变许多领域的运作方式,就连「学英文」也不例外!我发现ChatGPT应用在英语的学习与教学上非常有意思。 究竟ChatGPT如何改变英文学习者(学生)与教学者(老师)呢? 有5个应用场景我感到…...

基于spirngboot人事考勤管理信息系统
一:功能介绍 本系统前端采用vue框架以及Elemnt-UI,后端采用springboot、mysql、redis、mybatis等技术栈。 主要功能有登录、员工考勤、数据统计、薪资管理、权限管理、打卡管理、考勤审核、请假审批、薪资发放、报表统计、文件上传、文件下载、考勤设置、请假设置。…...
QT界面窗口 (widget)的显示和隐藏,关闭
QT界面窗口的显示和隐藏,关闭_qt窗口隐藏关闭按钮_123无敌,就你了的博客-CSDN博客...
这7个AI软件让设计效率飞起,快来收藏 优漫动游
伴随着AI技术的发展,设计师使用AI工具来提高工作效率已成为一种趋势,越来越多的AI工具也出现在市场上。本文收集了市场上7个好用的AI工具推荐给大家,一起来看看吧! 这7个AI软件让设计效率飞起,快来收藏 1、即时AI…...

ElasticSearch环境准备
Elasticsearch 是一个基于 Apache Lucene™ 的开源搜索引擎。不仅仅是一个全文搜索引擎,它还是一个分布式的搜索和分析引擎,可扩展并能够实时处理大数据。以下是关于 Elasticsearch 的一些主要特点和说明: 1.实时分析:Elasticsear…...
JAVA练习百题之数组插入元素
题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。 程序分析 要将一个数插入已经排好序的数组中,我们可以采用以下步骤: 遍历数组,找到第一个大于待插入数的位置。将待插入数插入到该位…...
C++11常见语法
目录 lambda 表达式 可变模板参数 C11新类的默认函数 包装器 function bind lambda 表达式 lambda 表达式也是可调用对象,在C语言中就有函数指针,但是函数指针比较复杂。 而在C11之前,也有仿函数,使用仿函数,还…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...