【c++设计模式17】行为模式2:命令模式(Command Pattern)

【c++设计模式17】行为模式2:命令模式(Command Pattern)

  • 一、定义
  • 二、适用场景
  • 三、过程
  • 四、命令模式类图
  • 五、C++示例代码
  • 六、使用注意事项

原创作者:郑同学的笔记
原创地址:https://zhengjunxue.blog.csdn.net/article/details/132589679
qq技术交流群:921273910

类型序号设计模式描述
行为模式1责任链模式
(Chain of Responsibility)
将这些处理者连成一条链。 链上的每个处理者都有一个成员变量来保存下一个处理者。
2命令模式
(Command Pattern)
它将请求封装为一个对象,从而使得可以用不同的请求对客户端进行参数化或将请求放入队列中
3迭代器模式
(Iterator Pattern)
它提供了一种顺序访问聚合对象中各个元素的方法,而不暴露其内部表示。
4中介者模式
(Mediator Pattern)
通过中介对象进行通信,从而降低了对象之间的耦合性。
5备忘录模式
(Memento Pattern)
当需要保存和恢复对象的状态时,可以使用备忘录模式。
6观察者模式
(Observer Pattern)
当一个对象的状态发生改变时,所有依赖它的对象都会自动收到通知并更新。
7策略模式
(Strategy Pattern)
定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。客户端代码在运行时选择所需的算法。
8状态模式
(State Pattern
是在一个类的内部会有多种状态的变化,因为状态变化从而导致其行为的改变,在类的外部看上去这个类就像是自身发生了改变一样。
9模板方法模式
(Template Method Pattern)
定义了算法的基本骨架,而具体方法则由子类提供具体实现。
10访问者模式
(Visitor Pattern)
访问者定义了针对不同元素的操作方法,而元素则是被访问者访问的对象。

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而使不同的请求能够以参数化的方式进行参数化,并且能够对请求进行排队或记录日志,以及支持可撤销的操作。

一、定义

命令模式定义了一个抽象命令(Command)接口和具体命令(Concrete Command)类,每个具体命令类都实现了抽象命令接口。命令对象包含了执行操作的方法,将请求的发送者(Invoker)和接收者(Receiver)解耦,使得请求的发送者不需要知道请求的处理细节。请求的发送者只需要通过调用命令对象的执行方法来触发请求的处理。

二、适用场景

命令模式适用于以下情况:

  • 当需要将请求发送者和接收者解耦时,采用命令模式可以实现对象之间的松耦合。
  • 当需要对请求进行参数化时,可以使用命令模式将请求封装为一个对象,并将特定的请求参数传递给该对象。
  • 当需要支持撤销操作时,可以使用命令模式来保存请求的历史记录,方便撤销和重做操作。
  • 当需要将一些操作封装成一系列的高级操作时,可以使用命令模式来组合这些操作。

三、过程

命令模式的过程包括以下几个角色:

  • 命令接口(Command Interface):定义命令的统一接口,声明执行命令的方法。
  • 具体命令(Concrete Command):实现命令接口,封装了具体的请求操作和接收者。
  • 命令发送者(Command Sender):负责创建具体命令对象,并将其发送给命令接收者执行。
  • 命令接收者(Command Receiver):执行具体命令所定义的操作。

四、命令模式类图

  • 请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
  • Command 模式的最终目的就是将一个请求封装成一个对象,
  • 这些命令的接收者是电视class TVReceiver,命令被分离出来实现了和电视类的解耦合。通过这种方式可以控制命令执行的时机,

在这里插入图片描述

五、C++示例代码

以下是一个使用命令模式的示例代码,在这个示例中,我们将以电视遥控器控制功能为例,展示如何使用命令模式来实现:

#include <iostream>// 命令接收者:电视
class TVReceiver {
public:void turnOn() {std::cout << "电视已打开" << std::endl;}void turnOff() {std::cout << "电视已关闭" << std::endl;}
};// 命令接口:电视命令
class TVCommand {
protected:TVReceiver* receiver;
public:virtual void execute() = 0;
};// 具体命令:打开电视
class TurnOnTVCommand : public TVCommand {public:explicit TurnOnTVCommand(TVReceiver* receiver) {}void execute() override {receiver->turnOn();}
};// 具体命令:关闭电视
class TurnOffTVCommand : public TVCommand {
/*private:TVReceiver* receiver*/;public:explicit TurnOffTVCommand(TVReceiver* receiver)  {}void execute() override {receiver->turnOff();}
};// 命令发送者:遥控器
class RemoteController {
private:TVCommand* command;public:void setCommand(TVCommand* command) {this->command = command;}void pressButton() {std::cout << "按下按钮,执行命令:" << std::endl;command->execute();}
};int main() {TVReceiver* tv = new TVReceiver();TurnOnTVCommand* turnOnCommand = new TurnOnTVCommand(tv);TurnOffTVCommand* turnOffCommand = new TurnOffTVCommand(tv);RemoteController* remote = new RemoteController();// 设置具体命令remote->setCommand(turnOnCommand);remote->pressButton();      // 打开电视remote->setCommand(turnOffCommand);remote->pressButton();      // 关闭电视delete tv;delete turnOnCommand;delete turnOffCommand;delete remote;return 0;
}

输出

在这里插入图片描述

在上述示例中,我们定义了命令接口 TVCommand,其中声明了一个 execute() 方法来执行电视的相应操作。

具体命令类 TurnOnTVCommand 和 TurnOffTVCommand 实现了 TVCommand 接口,封装了打开和关闭电视的具体操作。

命令发送者 RemoteController 负责持有具体命令对象,并通过调用命令对象的 execute() 方法来执行相应操作。

命令接收者 TVReceiver 定义了电视的操作方法。

在 main 函数中,我们实例化了电视、具体命令对象和遥控器,并进行相应的操作。

六、使用注意事项

命令模式可以将请求发送者和接收者解耦,但也会增加类数量。需要权衡哪些操作适合使用命令模式。
需要注意命令之间的依赖关系,避免形成闭环依赖。
命令模式可以支持撤销操作,可以在命令接口中添加撤销方法来实现。
为了方便处理多个命令的批量执行,可以使用宏命令(Macro Command)来组合多个命令。

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

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

相关文章

做外贸你以为客户会懂,但是你还是要讲出来!

很多人都认为&#xff0c;我们公司介绍里啥都有&#xff0c;公司规模有多大&#xff0c;认证有哪些&#xff0c;产品能做什么&#xff1f;我们写在那里&#xff0c;客户就应该懂。 其实&#xff0c;不是的。 客户真的关注不了那么多&#xff0c;可能看到了&#xff0c;也就是看…

运维工具 - SFTP 和 FTP 的区别?

SFTP 和 FTP 的区别有三点 连接方式 SFTP 是在客户端和服务器之间通过 SSH 协议建立的安全连接来传输文件&#xff0c;而 FTP 则是 TCP 端口 21 上的控制连接建立连接。 安全性 SFTP 使用加密传输认证信息来传输数据&#xff0c;因此 SFTP 相对于 FTP 更安全的。 效率 SF…

Windows Linux下查看静态库,动态库各种命令的总结

Windows环境下查看库文件 静态库(.lib) 使用lib.exe查看库内容 命令示例:lib /list C.lib使用dumpbin.exe查看库的详细信息 命令示例:dumpbin /headers C.lib动态链接库(.dll) 使用dumpbin.exe查看DLL的导出信息 命令示例:dumpbin /exports B.dll

Android Studio的Gradle面板里不显示task,build ,assemble 无法出aar包

按照以下方式把对应开关打开就可以正常进行build/assemble进行aar的生成了

多级菜单的实现一

总共分享三种实现多级菜单方式&#xff0c;前面两种是裸机式的&#xff0c;第三种是带有FreeRTOS。 1、首先处在第一级菜单&#xff1a;显示 同时按下一项按钮&#xff0c;flag会变化&#xff0c;光标会根据flag的值&#xff0c;在界面上不同位置显示出光标 按下确定&#xff…

Linux系统中qfile调用seek无法更新指定位置文件内容

一、问题描述 最近在移植qt程序到银河麒麟系统中&#xff0c;发现在Windows下调用seek接口更新二进制文件功能在麒麟系统中总是无法实现更新&#xff0c;调用的QFile接口也并未报错。 原代码实现方式如下&#xff1a; if (!m_writeFile->open(QIODevice::WriteOnly | QIODe…

开源工具专题-04 Atlassian Crowd部署备份及迁移

开源工具专题-04 Atlassian Crowd部署备份及迁移 注&#xff1a; 本教程由羞涩梦整理同步发布&#xff0c;本人技术分享站点&#xff1a;blog.hukanfa.com转发本文请备注原文链接&#xff0c;本文内容整理日期&#xff1a;2024-05-29csdn 博客名称&#xff1a;五维空间-影子&…

使用libgpiod库中的事件方式监测多个输入事件

Linux下要同时检测多个GPIO输入的方法有很多&#xff0c;这里我使用libgpiod库中的API实现多个GPIO输入检测&#xff0c;可以达到类似STM32利用外部中断实现输入事件检测的效果&#xff0c;示例代码如下所示&#xff1a; /* 示例使用的libgpiod库版本为V1.2.1 */ //示例功能是…

2022.9.26DAY678

课程学习&#xff1a;《数据处理技术》讲了“数据查询”的语法格式&#xff0c;语法格式也算是简单&#xff0c;就是没能跟之前的内容联系起来&#xff0c;之前的内容没有及时回顾。 高等数学&#xff1a;“ 函数的概念”&#xff0c;讲了函数的概念&#xff0c;反函数&#…

make_ext4fs:not found

报错信息&#xff1a; 解决&#xff1a; sudo apt-get install android-tools-fsutils sudo apt-get install android-sdk-libsparse-utils sudo apt-get install android-sdk-ext4-utils

跟TED演讲学英文:Let your garden grow wild by Rebecca McMackin

Let your garden grow wild Link: https://www.ted.com/talks/rebecca_mcmackin_let_your_garden_grow_wild Speaker: Rebecca McMackin Date: October 2023 文章目录 Let your garden grow wildIntroductionVocabularySummaryTranscriptAfterword Introduction Many garden…

怎么等比例缩小图片尺寸?这四种方法肯定可以帮到你!

怎么等比例缩小图片尺寸&#xff1f;在当今日常生活中&#xff0c;图片文件是我们不可或缺的一部分&#xff0c;它们以各种形式出现&#xff0c;从社交媒体上的照片到工作文档中的插图&#xff0c;然而&#xff0c;随之而来的问题是&#xff0c;有时这些图片文件的尺寸过大&…

Threejs墙体挖洞做门或窗

在使用Threejs代码构建的展厅中&#xff0c;需要在一面墙中间挖个洞作为门或窗户&#xff0c;效果如下&#xff1a; 引入ThreeBSP.js <script src"plugins/three/ThreeBSP.js"></script> 创建 // 1 定义墙面var cubeGeometry new THREE.BoxGeometry(1…

使用 LiteGraph.js 构建可视化工作流图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 使用 LiteGraph.js 构建可视化工作流图 应用场景介绍 LiteGraph.js 是一个轻量级的开源 JavaScript 库&#xff0c;用于构建可视化工作流图。它广泛应用于游戏开发、数据可视化、交互式叙事等领域。 代码基本…

2024会声会影激活码免费注册码大揭秘!

在当今数字化时代&#xff0c;视频编辑已经成为了许多人日常生活和工作中不可或缺的一部分。无论是制作短视频、Vlog还是专业影视剪辑&#xff0c;一款优秀的视频编辑软件都能让我们事半功倍。而市面上众多的视频编辑软件中&#xff0c;会声会影无疑是备受瞩目的一款。本文将为…

【全开源】知识库文档系统(ThinkPHP+FastAdmin)

&#x1f4da;知识库文档系统&#xff1a;解锁知识的无限可能 一款基于ThinkPHPFastAdmin开发的知识库文档系统&#xff0c;可用于企业工作流程的文档管理&#xff0c;结构化记录沉淀高价值信息&#xff0c;形成完整的知识体系&#xff0c;能够轻松提升知识的流转和传播效率&a…

收银系统源码-千呼新零售2.0【合作案例】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

英伟达唯一指定液冷散热供应商维谛技术的股价还有巨大的上涨空间

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 在“全球AI风向标”英伟达带来的超额回报影响下&#xff0c;以及华尔街持续看好英伟达后续走势的带动下&#xff0c;美股已经掀起了一场AI“淘金热”。猛兽财经将在本文中详细介绍一下我们之前就非常看好的一家在全球AI产业…

vue的elementUI的el-tree的选择

有一棵树型的数据,需要实现:在外部加一个 全选和不全选的按钮,去全部勾选树结构里面每一项的选框。 当点击勾选全选的时候,树的每一项都勾选; 当取消全选的时候,树的每一项都不勾选; 当选树的其中一项时,全选按钮是半选状态; 实现效果如下: <template><…

动态规划——浅谈dp如何入门,以及入门题目(值得收藏,持续更新)

前言 动态规划如何入门?如果你问我怎么精通,那我只能告诉你我也不知道,但你要问我怎么入门,那我就可以和你说道说道了. 我并没有能力也不想说你看完就会了,我只是想给大家开个头,你只要知道怎么写了怎么去思考了,你就可以通过刷题来强化思维了,能走多远就看各位的造化了! 动…