C++设计模式----命令模式

1、介绍

        命令模式是⼀种⾏为型设计模式,其允许将请求封装成⼀个对象(命令对象,包含执⾏操作所需的所有信息),并将命令对象按照⼀定的顺序存储在队列中,然后再逐⼀调用执⾏,这些命令也可以⽀持反向操作,进⾏撤销和重做。

        命令模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作

创建步骤:

        (1)定义抽象命令类(Command):创建一个抽象类或者接口,其中包含一个纯虚的执行方法,用于执行具体的命令操作。
        (2)创建具体命令类(Concrete Command):继承自抽象命令类,实现具体的命令操作,同时持有一个命令接收者对象。
        (3)定义命令接收者类(Receiver):这个类包含实际执行命令操作的方法。
        (4)创建调用者类(Invoker):这个类负责存储和执行命令对象,可以包含一个命令队列,用于存储多个命令对象。

优点:

        (1)降低系统耦合度:将命令的发送者与接收者解耦,方便系统的扩展和维护。

        (2)支持命令的撤销和重做:可以灵活地实现对命令的操作历史记录。

        (3)增加系统的灵活性:可以方便地添加新的命令。

缺点:

        (1)可能导致系统类的数量增加:需要定义多个命令类和相关的处理类。

2、示例

#include <iostream>  
#include <vector>  
#include <string>  

// 接收者接口  
class Receiver {//子类必须重写抽象类中所有的纯虚函数,否则子类也是抽象类
public:
    virtual void turnOn(std::string light) = 0;
    virtual void setSpeed(int speed) = 0;
};

// 具体接收者  
class LightReceiver : public Receiver {
public:
    void turnOn(std::string light) override {//只重写抽象类中的turnOn函数,LightReceiver也会变为抽象类
        std::cout << "Turning on " << light << std::endl;
    }
    void setSpeed(int speed) override {
        std::cout << "Setting fan speed to " << speed << std::endl;
    }
};

// 具体接收者  
class Fan : public Receiver {
public:
    void turnOn(std::string light) override {
        std::cout << "Turning on " << light << std::endl;
    }
    void setSpeed(int speed) override {
        std::cout << "Setting fan speed to " << speed << std::endl;
    }
};


// 命令接口  
class Command {
public:
    virtual void execute() = 0;
};

// 具体命令  
class LightCommand : public Command {
public:
    LightCommand(LightReceiver*pLight,std::string light) : m_pLight(pLight),light_(light) {}
    void execute() override {
        std::cout << "Turning on " << light_ << std::endl;
        m_pLight->turnOn(light_);
    }
private:
    std::string light_;
    LightReceiver* m_pLight;
};

// 具体命令  
class FanCommand : public Command {
public:
    FanCommand(Fan* pFan,int speed) : m_pFan(pFan),speed_(speed) {}
    void execute() override {
        std::cout << "Setting fan speed to " << speed_ << std::endl;
        m_pFan->setSpeed(speed_);
    }
private:
    int speed_;
    Fan* m_pFan;
};

// 调用者接口  
class Invoker {
public:
    virtual void setCommand(Command* command) = 0;
    virtual void execute() = 0;
};

// 具体调用者  
class LightInvoker : public Invoker {
public:
    void setCommand(Command* command) override { m_pCommand = command; }
    void execute() override { m_pCommand->execute(); }
private:
    Command* m_pCommand;
};

int main() {
    LightReceiver light;
    LightCommand lightCommand(&light,"kitchen");
    LightInvoker lightInvoker;
    lightInvoker.setCommand(&lightCommand);
    lightInvoker.execute(); // 执行命令,调用接收者的turnOn方法,输出"Turning on kitchen"  
    return 0;
}

结果:

Turning on kitchen
Turning on kitchen

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电阻式无功负载组(即电阻式感性负载组)

RL系列电阻式无功负载组&#xff08;即电阻式感性负载组&#xff09;可以通过设置特定功率因数&#xff08;pf&#xff09;来模拟电力系统中的电机负载和电磁器件以及纯阻性负载。电阻式无功负载组是需要额定kVA、额定功率因数和额定电流测试的关键任务备用应急电源系统定期进行…

Mybatis-01 原理

一. JDBC式编程 在 jdbc 编程中&#xff0c;我们最常用的是 PreparedStatement 式的编程&#xff0c;我们看下面这个例子&#xff1b; Connection conn null; PreparedStatement ps null; ResultSet rs null;try {// 1. 注册驱动Class.forName("com.mysql.jdbc.Drive…

UE5 01-给子弹一个跟角色一致的向前的方向的冲量

默认Pawn 负责角色位置, 默认PlayerController 负责记录角色相机旋转

Vant Design - VUE 时间区间限制

效果图&#xff0c;限制7天 实现代码 <a-range-picker v-model"dateTime" style"width: 100%" :disabled-date"disabledDate" format"YYYY-MM-DD HH:mm:ss" :showTime"true" :placeholder"[开始时间, 结束时间]&quo…

图像增强 目标检测 仿射变换 图像处理 扭曲图像

1.背景 在目标检测中&#xff0c;需要进行图像增强。这里的代码模拟了旋转、扭曲图像的功能&#xff0c;并且在扭曲的时候&#xff0c;能够同时把标注的结果也进行扭曲。 这里忽略了读取xml的过程&#xff0c;假设图像IMG存在对应的标注框&#xff0c;且坐标为左上、右下两个…

黑龙江等保测评知多少

黑龙江的等保测评&#xff0c;即网络安全等级保护测评&#xff0c;是指在中国黑龙江地区针对信息系统的安全性进行的一系列评估活动&#xff0c;确保这些系统符合国家规定的安全等级标准。这个过程涉及到多个阶段&#xff0c;旨在提升信息系统整体的安全水平。 以下是黑龙江等…

程序包lombok不存在,解决办法。

当前方法是针对于代码没有报错&#xff0c;本身有lombok jar包的情况 1.找到本地maven仓库中的已经下载好的lombok包&#xff0c;删掉。 2. 直接刷新maven&#xff0c;会重新下载lombok jar包&#xff0c;此时再启动项目时就可以正常运行了。

第四届数字安全大会:AI时代数据安全策略与天空卫士创新实践

2024年6月22日&#xff0c;以 “新质•真能力”为主题的第四届数字安全大会在北京隆重召开。这场由数世咨询和CIO时代联合主办的行业盛会&#xff0c;集中探讨了大模型、数据治理与流通、以及安全运营等当前最前沿的议题。大会吸引了来自不同行业的首席信息官&#xff08;CIO&a…

和闺蜜的泰国之旅

每当我回想起那次和闺蜜丽丽&#xff08;全名罗莉&#xff09;的泰国之旅&#xff0c;心中总是涌起复杂的情绪。那段经历仿佛一场噩梦&#xff0c;至今仍无法从脑海中挥去。 我们满怀期待地抵达曼谷&#xff0c;热带的阳光、繁忙的街道、美味的街头小吃&#xff0c;都让我们兴…

用例子和代码了解词嵌入和位置编码

1.嵌入&#xff08;Input Embedding&#xff09; 让我用一个更具体的例子来解释输入嵌入&#xff08;Input Embedding&#xff09;。 背景 假设我们有一个非常小的词汇表&#xff0c;其中包含以下 5 个词&#xff1a; "I""love""machine"&qu…

【后端面试题】【中间件】【NoSQL】MongoDB提高可用性的方案(主从结构、仲裁节点、分片、写入语义)

主从结构 MongoDB的高可用和别的中间件的高可用方案基本类似。比如在MySQL里&#xff0c;接触了分库分表和主从同步&#xff1b;在Redis里&#xff0c;Redis也有主从结构&#xff1b;在Kafka里&#xff0c;分区也是有主从结构的。 所以先介绍启用了主从同步 我们的系统有一个关…

使用ChatGPT自动生成测试用例思维导图

使用ChatGPT自动生成测试用例思维导图 引言ChatGPT在测试用例编写中的应用全面覆盖测试场景边界测试避免测试用例重复 借助ChatGPT生成测试用例思维导图准备工作步骤一&#xff1a;与ChatGPT对话步骤二&#xff1a;生成思维导图代码 结语 引言 在编写测试用例时&#xff0c;测…

物联网应用Fast ingest

一、原文路径 Tuning the System Global Area 二、翻译 1、原理 Fast ingest 优化是针对高并发&#xff0c;单行数据的插入这种场景的。比如IOT应用采集&#xff08;很符合国网的用采数据场景&#xff09;。 Fast ingest 使用MEMOPTIMIZE_WRITE 提示来插入数据到 MEMOPTIM…

WordPress付费进群V2主题,多种引流方法,引私域二次变现

全新前端UI界面&#xff0c;多种前端交互特效让页面不再单调&#xff0c;进群页面群成员数&#xff0c;群成员头像名称&#xff0c;每次刷新页面随机更新不重复&#xff0c;最下面评论和点赞也是如此随机刷新不重复 进群页面简介&#xff0c;群聊名称&#xff0c;群内展示&…

thinkphp6/8 验证码

html和后台验证代码按官方来操作 ThinkPHP官方手册 注意&#xff1a; 如果验证一直失败&#xff0c;看看Session是否开启&#xff0c; 打印dump(session_status());结果2为正确的&#xff0c; PHP_SESSION_DISABLED: Session功能被禁用&#xff08;返回值为0&#xff09;。…

WAF的新选择,雷池 SafeLine-安装动态防护使用指南

什么是 WAF WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。 区别于传统防火墙&#xff0c;WAF 工作在应用层&#xff0c;对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果&#xff0c;使其免于受到黑客的攻击&#xff1b; 通俗来讲&#…

vue3+ts项目中.env配置环境变量与情景配置

一、环境变量配置 官网https://cn.vitejs.dev/guide/env-and-mode.html#intellisense 1. 新建.env开头的文件在根目录 为了防止意外地将一些环境变量泄漏到客户端&#xff0c;只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码 .env 所有环境默认加载 .env.developm…

C++ 语法

一、头文件与源文件 头文件用于声明函数,类似于java中service层的接口; 源文件用于实现头文件函数,相当于java中serviceImpl层的实现类; 定义接口 实现接口 使用接口 二、指针概述 定义与使用 定义一个指针p用于存a变量的内存地址,即指针就是地址; 解引用可以获取或修改…

并发编程面试题1

一、原子性高频问题: 1.1 Java中如何实现线程安全? 多线程操作共享数据会出现问题。可以使用锁来解决: 悲观锁: 使用 synchronized 和 Lock乐观锁: 使用 CAS(Compare-And-Swap)可以根据业务情况选择 ThreadLocal,让每个线程处理自己的数据。 1.2 CAS底层实现 回答思…

Prometheus 监控服务器

Prometheus概述 组件化设置&#xff1a;nginx ,ceph , Prometheus 部署Prometheus服务器 配置时间 安装Prometheus服务器 访问web页面&#xff1a;http://192.168.88.5:9090/ 添加被监控端 监控方式&#xff1a; 拉取&#xff1a;pull。监控端联系被监控端&#xff0c;采集数…