C++设计模式之——命令模式

命令模式

  • 概念
  • 创建步骤
  • 示例
    • 示例一
      • 代码实现
      • 运行结果
    • 示例二
      • 代码实现
      • 运行结果
    • 示例三
      • 示例代码
      • 运行结果
    • 示例四
      • 代码实现
      • 运行结果
  • 应用场景

概念

命令模式是一种行为型设计模式,它允许将请求封装为一个对象,从而使得可以参数化客户端请求、将请求排队或者记录请求日志,以及支持可撤销的操作。

在C++中,命令模式通常由一个抽象命令类、具体命令类、命令接收者类和调用者类组成。

创建步骤

命令模式的主要步骤包括:

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

示例

示例一

代码实现

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

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

// 接收者接口  
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 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;
}

运行结果

在这里插入图片描述

示例二

代码实现

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

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

// 具体命令 - 加法命令  
class AddCommand : public Command {
public:
    AddCommand(int a, int b) : a_(a), b_(b) {}
    void execute() override {
        std::cout << "Result: " << a_ + b_ << std::endl;
    }
private:
    int a_, b_;
};

// 具体命令 - 减法命令  
class SubtractCommand : public Command {
public:
    SubtractCommand(int a, int b) : a_(a), b_(b) {}
    void execute() override {
        std::cout << "Result: " << a_ - b_ << std::endl;
    }
private:
    int a_, b_;
};

// 调用者 - 计算器  
class Calculator {
public:
    void addCommand(Command* command) {
        commands_.push_back(command);
    }
    void executeCommands() {
        for (auto command : commands_) {
            command->execute();
        }
    }
    ~Calculator() 
    {
        for (const auto &command: commands_)
        {
            delete command;
        }
    }
private:
    std::vector<Command*> commands_;
};

int main() {
    Calculator calculator;
    calculator.addCommand(new AddCommand(5, 3)); // 添加加法命令,执行后输出"Result: 8"  
    calculator.addCommand(new SubtractCommand(10, 4)); // 添加减法命令,执行后输出"Result: 6"  
    calculator.executeCommands(); // 执行所有命令,依次输出"Result: 8"和"Result: 6"  
    return 0;
}

运行结果

在这里插入图片描述

示例三

示例代码

#include <iostream>
#include <vector>

// 抽象命令类
class Command {
public:
    virtual void execute() = 0;
};

// 命令接收者类
class Receiver {
public:
    void action() {
        std::cout << "Receiver action" << std::endl;
    }
};

// 具体命令类
class ConcreteCommand : public Command {
private:
    Receiver* receiver;

public:
    ConcreteCommand(Receiver* recv) : receiver(recv) {}

    void execute() {
        receiver->action();
    }
};


// 调用者类
class Invoker {
private:
    std::vector<Command*> commands;

public:
    void addCommand(Command* cmd) {
        commands.push_back(cmd);
    }

    void executeCommands() {
        for (Command* cmd : commands) {
            cmd->execute();
        }
    }
};

int main() {
    Receiver* receiver = new Receiver();
    ConcreteCommand* cmd = new ConcreteCommand(receiver);

    Invoker invoker;
    invoker.addCommand(cmd);
    invoker.executeCommands();

    delete receiver;
    delete cmd;

    return 0;
}

运行结果

在这里插入图片描述

示例四

代码实现

#include <iostream>
#include <vector>

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

// 具体命令类 - 打开电视
class TurnOnTVCommand : public Command {
public:
    void execute() {
        std::cout << "Turning on the TV" << std::endl;
    }
};

// 具体命令类 - 关闭电视
class TurnOffTVCommand : public Command {
public:
    void execute() {
        std::cout << "Turning off the TV" << std::endl;
    }
};

// 遥控器
class RemoteControl {
private:
    Command* command;

public:
    void setCommand(Command* cmd) {
        command = cmd;
    }

    void pressButton() {
        command->execute();
    }
};

int main() {
    RemoteControl remote;

    TurnOnTVCommand onCommand;
    TurnOffTVCommand offCommand;

    remote.setCommand(&onCommand);
    remote.pressButton();

    remote.setCommand(&offCommand);
    remote.pressButton();

    return 0;
}

运行结果

在这里插入图片描述

应用场景

1.实现宏命令:命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
2.日志记录和事务处理:在命令模式中,可以方便地增加额外功能,比如日志记录。此外,如果一个操作需要由多个子操作构成,而这些子操作需要被打包在一起作为一个单独的事务来执行,命令模式可以帮助实现这一功能。
3.支持撤销和重做:命令模式可以方便地实现撤销(Undo)和重做(Redo)功能。
4.队列请求:当需要将请求排队,例如用户界面中的点击事件或网络请求,命令模式可以将这些请求封装为对象并放入队列中等待处理。
5.多线程操作:命令模式可以帮助多线程操作,多个线程可以发出操作命令,程序可以在后台自动发出指令并处理其他业务,而不用等待线程完成操作。
6.系统需要将请求调用者和请求接收者解耦:命令模式使调用者和接收者不直接交互。
7.系统随机请求命令或经常增加、删除命令:命令模式可以方便地实现这些功能。
8.当系统需要执行一组操作时:命令模式可以定义宏命令来实现该功能。

总的来说,命令模式的应用场景主要在于解耦请求与实现,封装接收方具体命令的实现细节,使得请求方的代码架构稳定,具备良好的扩展性。

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

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

相关文章

npm login报错:Public registration is not allowed

npm login报错:Public registration is not allowed 1.出现场景2.解决 1.出现场景 npm login登录时,出现 2.解决 将自己的npm镜像源改为npm的https://registry.npmjs.org/这个&#xff0c;解决&#xff01;

安防视频云平台/可视化监控云平台EasyCVR获取设备录像失败,该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。GB28181音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视…

打响指针的第一枪:指针家族

前言 指针其实是我们学习C语言中最难的知识点&#xff0c;很多人在学习指针的时候会被绕晕&#xff0c;包括博主也是&#xff0c;当初百思不得其解&#xff0c;脑袋都要冒烟了&#xff0c;本来打算在学习指针的时候就写一篇博客&#xff0c;但是当初自己的能力还是没有办法去完…

harmonyOS 自定义组件基础演示讲解

上文 HarmonyOS组件属性控制 链式编程格式推荐我们讲了一些系统组件 可以传入一些事件和参数 来达到一些不同的效果 其实 我们还可以用自己写的组件 那么 组件这么写&#xff1f; 其实 我们的 page 内部结果 就是一个组件 harmonyOS的概念 万物皆组件 那么 我们就可以在他下面…

低代码软件开发的革命

一、前言 如果一个概念能在科技圈火起来&#xff0c;它往往兼具字面简明和内涵丰富的特征&#xff0c;并具有某种重塑产业格局的潜力。低代码&#xff08;Low Code&#xff09;就是这样一个典型。顾名思义&#xff0c;低代码是指少用代码&#xff0c;甚至不用代码&#xff0c;仅…

自动化测试 (五) 读写64位操作系统的注册表

自动化测试经常需要修改注册表 很多系统的设置&#xff08;比如&#xff1a;IE的设置&#xff09;都是存在注册表中。 桌面应用程序的设置也是存在注册表中。 所以做自动化测试的时候&#xff0c;经常需要去修改注册表 Windows注册表简介 注册表编辑器在 C:\Windows\regedit…

Netty入门基础知识

简介 Netty是一款高性能java网络编程框架&#xff0c;被广泛应用在中间件、直播、社交、游戏等领域。Netty对java NIO进行高级封装&#xff0c;简化了网络应用的开发过程。 stream与channel stream不会自动缓冲数据&#xff0c;channel会利用系统提供的发送缓冲区&#xff0c;接…

科创金融的向善力量:浙商银行多措并举赋能科创企业,打造科技金融服务生态圈

近日&#xff0c;浙商银行科技金融服务发布会在杭州举行。 发布会以“智汇科创&#xff0c;善行未来”为主题&#xff0c;围绕科技金融服务“向善”新生态&#xff0c;浙商银行重磅推出科创企业全图景服务方案&#xff0c;正式发布科创积分贷&#xff0c;与浙江大学联合发布人…

初冬天气变化大,长辈身上的这些小毛病千万不能轻视

心率、血氧、肺功能&#xff0c;甚至是一次次不起眼的咳嗽&#xff0c;背后都可能藏着健康问题。但是我们可以利用好手表上的健康检测功能&#xff0c;提前获知健康数据的变化&#xff0c;有的放矢&#xff0c;科学应对身体的不适&#xff0c;度过一个有准备的温暖冬天&#xf…

【JVM从入门到实战】(七)Java内存区域

运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。 《Java虚拟机规范》中规定了每一部分的作用 线程不共享&#xff1a;程序计数器、虚拟机栈、本地方法栈 线程共享&#xff1a;方法区&#xff0c;堆 1. 程序计数器(Program Count…

定位咨询:企业市场竞争中的定海神针

什么是定位咨询?定位咨询能给企业带来什么帮助?在现代市场的激烈竞争中&#xff0c;定位咨询不仅是企业区分自己的重要工具&#xff0c;更是它们赢得市场份额的关键。以下是定位咨询的定义和几个核心方面&#xff0c;笔者将列举具体案例说明其重要性和实用性。 定位咨询的简单…

kafka文件存储机制

Topic分为好几个partition分区&#xff0c;每个分区对应于一个log文件&#xff0c;log文件其实是虚的&#xff0c;Kafka采取了分片和索引机制&#xff0c; 将每个partition分为多个segment&#xff08;大小为1G&#xff09;。每个segment包括&#xff1a;“.index”文件、“.lo…

SiLM5350MDBCA-DG车规级隔离驱动芯片,我们能为汽车智能提供什么?

SiLM5350MDBCA-DG是一款适用于IGBT、MOSFET的单通道 隔离门极驱动器&#xff0c;具有10A拉电流和10A灌电流驱动能 力。提供内部钳位功能&#xff0c;可单独控制 上升时间和下降时间。 在 SOP8 封 装 中 具 有 3000VRMS 隔 离 耐 压 &#xff08; 符 合 UL1577&#xff09;。 与…

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph API资源对象StorageClass SC的主要作用在于&#xff0c;自动创建PV&#xff0c;从而实现PVC按需自动绑定PV。 下面我们通过创建一个基于NFS的SC来演示SC的作用。 要想使用NFS的SC&#xff0c;还需要安装一个NFS…

SMART PLC多路复用器功能块

SMART PLC指针应用介绍: https://rxxw-control.blog.csdn.net/article/details/123890483https://rxxw-control.blog.csdn.net/article/details/123890483SMART PLC指针在配方上的应用 https://rxxw-control.blog.csdn.net/article/details/122090212

CogVLM与CogAgent:开源视觉语言模型的新里程碑

引言 随着机器学习的快速发展&#xff0c;视觉语言模型&#xff08;VLM&#xff09;的研究取得了显著的进步。今天&#xff0c;我们很高兴介绍两款强大的开源视觉语言模型&#xff1a;CogVLM和CogAgent。这两款模型在图像理解和多轮对话等领域表现出色&#xff0c;为人工智能的…

使用P3口流水点亮8位LED

#include<reg51.h> //包含单片机寄存器的头文件 /**************************************** 函数功能&#xff1a;延时一段时间 *****************************************/ void delay(void) { unsigned char i,j; for(i0;i<250;i) fo…

推荐一款好用的PDF阅读器

下载地址: https://download.csdn.net/download/a876106354/88643909

导致OpenAI内乱的罪魁祸首,背后的技术是什么?

前几天围绕Sam 和 Greg和OpenAI board之间的爱恨情仇,我觉得比乡村爱情15还有意思,也达到了美剧多年未有的高度,反转反转再反转。 围绕争端的根本原因,那也是众说纷纭,不过其实有一条新闻我觉得挺值得玩味的,也是我所相信的,就是Sam在OpenAI day上发布了一个叫GP…

数据可视化---箱线图

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…