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

news2024/11/19 14:49:18

【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.coloradmin.cn/o/1791797.html

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

相关文章

面试官:你知道 ES6 的 生成器 Generator 吗?小明:说起 Generator,还得从我上次去餐馆点餐开始说起。

讲故事学 Generator 这篇文章先说一个小故事&#xff0c;作为引子&#xff0c;然后系统讲讲 Generator。阅读这篇文章的话&#xff0c;需要一些前置知识&#xff1a;起码用过 Promise 和 async/await。 小故事 吃货小明去了一家菜鸟镇非常有名的餐馆——《老三样餐馆》&…

如何修改cPanel面板的语言

本周有一个客户&#xff0c;购买Hostease的主机&#xff0c; 客户购买的是Linux虚拟主机&#xff0c;带cPanel面板的。询问我们的在线客服&#xff0c;他想修改cPanel面板的默认语言。Hostease虚拟主机默认英语&#xff0c;客户想要修改成中文。 在cPanel面板中修改语言设置是一…

3 - 大的国家(高频 SQL 50 题基础版)

3.大的国家 -- 查询属性&#xff1a;国家名称、人口和面积 select name,population,area fromWorld where area>3000000 OR population>25000000;

React中常见的面试题

本文是结合实践中和学习技术文章总结出来的笔记(个人使用),如有雷同纯属正常((✿◠‿◠)) 喜欢的话点个赞,谢谢! 1. 约束性组件与非约束性组件 1.1. 非约束性组件 非约束性组件其实就是不能控制状态的组件,比如: <input type"text" defaultValue"123&qu…

一个思维狂赚20万+?揭秘电商平台隐藏的流量认知!

你想要的流量&#xff0c;资源&#xff0c;人脉&#xff0c;都已经有人为你准备&#xff0c;你只需要找到拥有这些资源的人。对于流量和信息&#xff0c;也是一样&#xff0c;你想找的客户和产品&#xff0c;都已经有人为你准备在淘宝、拼多多等电商平台&#xff0c;你只需要找…

【踏雪无痕的痕六】——数学中有意思的问题

一、背景介绍 提出一个问题往往比解决一个问题更有意义&#xff0c;因为提出一个问题相当于提出了一个思考问题的维度&#xff1b;而解决一个问题是沿着这个维度将已有的知识串起来的过程 三、过程 1.数人数你会吗&#xff1f; 小名再第10位&#xff0c;小李再第15位&#…

VRTK4.0学习——(二)

手柄绑定以及显示 1.导入CameraRigs.UnityXRPluginFramework 和 CameraRigs.TrackedAlias 预设&#xff0c;将CameraRigs.UnityXRPluginFramework拖入CameraRigs.TrackedAlias的Elements中即可&#xff0c;运行软件后即可看到手柄了 注&#xff1a;如果无法看到手柄&#xff…

AI降痕工具使用指南:如何有效降低AIGC疑似度

随着人工智能技术的突飞猛进&#xff0c;AI生成内容&#xff08;AIGC&#xff09;已被广泛用于学术论文撰写中&#xff0c;提高效率同时也带来了原创性的挑战。面对日益严格的学术审查&#xff0c;一个突出的问题是&#xff1a;使用AI代写的论文能否通过内容检测&#xff1f;因…

《精品生活》万方普刊投稿发表简介

《精品生活》杂志是由国家新闻出版总署批准&#xff0c;南方出版传媒股份有限公司主管&#xff0c;广东大沿海出版工贸有限公司主办&#xff0c;广东精品生活杂志社出版的综合性文化期刊。主要栏目&#xff1a;教学研究、艺术教育、文化广角、民族文化、理论前沿、综合论坛。 刊…

生命周期钩子小案例

文章目录 一、在created中发送数据二、在mounted中获取焦点 一、在created中发送数据 <body><div id"app"><ul><li v-for"(item, index) in list" :key"item.id" class"news"><div class"left"…

从功能性磁共振成像(fMRI)数据重建音频

听觉是人类最重要的感官之一&#xff0c;它负责接收外部的听觉刺激&#xff0c;并将这些信息传递给大脑进行处理和理解。研究人员正致力于从神经科学和计算机科学两个领域探索人脑的听觉感知机制。一个关键目标是从人脑中解码神经信息&#xff0c;并重建原始的刺激。常见的大脑…

用友BIP收入云:助力旅游行业实现高效收入自动化,驱动收入增长

在数字化浪潮的推动下&#xff0c;旅游行业正经历着前所未有的变革。从传统的线下服务模式到线上线下融合&#xff0c;再到如今的智能化、自动化管理&#xff0c;每一步都标志着旅游行业向更高效、更精准、更便捷的方向发展。其中&#xff0c;收入管理作为旅游企业运营的核心环…

机器学习:更多关于元学习

目录 Meta Learning vs Self-supervised Learning 自监督学习——找初始化的参数MAML 自动学出合适的参数 MAML&#xff1a;不断的学初始化参数MAML的初始化参数来自BERT MAML&#xff1a;找出来的初始化参数能在训练任务上表现的很好BERT&#xff1a;自监督目标是不同的下游任…

msvcp140.dll是什么dll文件?msvcp140.dll文件的丢失要怎么去修复?

msvcp140.dll是什么dll文件&#xff1f;一般会问出这种问题的人&#xff0c;都是遇到了msvcp140.dll丢失的情况了&#xff0c;这时候你的一些程序是打不开的&#xff0c;你需要修复好msvcp140.dll文件才可以正常的打开程序&#xff0c;今天我们就来了解一下msvcp140.dll这文件&…

KT1025A的双模蓝牙芯片,参考标准蓝牙天线,蓝牙距离短,会卡

一、问题简介 使用KT1025A的双模蓝牙芯片&#xff0c;为什么我参考BT201或者BT301&#xff0c;或者BT321F设计的蓝牙天线&#xff0c;蓝牙距离短&#xff0c;会卡等等&#xff0c;这个可能是什么原因&#xff0c;如何改善呢&#xff1f; 问题详细分析 首先看看客户的板子PCB…

opencv快速安装以及各种查看版本命令

安装opencv并查看其版本&#xff0c;直接通过一个可执行文件实现。 #!/bin/bashwget https://codeload.github.com/opencv/opencv/zip/3.4 -O opencv-3.4.zip && unzip opencv-3.4.zip && cd opencv-3.4 && \mkdir build && cd build &&a…

C++--DAY3

思维导图 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std; class …

【文档智能】符合人类阅读顺序的文档模型-LayoutReader原理及权重开源

引言 阅读顺序检测旨在捕获人类读者能够自然理解的单词序列。现有的OCR引擎通常按照从上到下、从左到右的方式排列识别到的文本行&#xff0c;但这并不适用于某些文档类型&#xff0c;如多栏模板、表格等。LayoutReader模型使用seq2seq模型捕获文本和布局信息&#xff0c;用于…

品牌营销的“必杀技”,一文带你看懂如何实现精准营销

你在遇到疑惑寻求解决方法时是否会优先想到“百度一下”&#xff1f;我们脑中的优先选择其实就是品牌将自身特点结合其目标用户信息采取精准营销从而完成的广告信息的成功投放。而精准营销&#xff0c;作为一种现代化的广告营销方式&#xff0c;已成为品牌营销的新趋势&#xf…

varchar 字段扩展问题

背景 近期接到一个产品需求&#xff0c;由于上游业务字段扩大了字段&#xff0c;下游的字段也得跟着调整扩大&#xff0c;这就涉及几十张大表&#xff0c;十几亿行数据的变更。 如果按照传统方式 onlie-ddl 借用第三方工具也得三四天分批跑&#xff0c;看了看MySQL官网&#…