0

0

C++中如何实现命令模式 请求封装与执行解耦的实现方式

P粉602998670

P粉602998670

发布时间:2025-07-25 08:13:01

|

194人浏览过

|

来源于php中文网

原创

命令模式在c++++中通过将请求封装为对象实现解耦,主要由command、concretecommand、invoker、receiver和client组成。1. command定义执行接口;2. concretecommand绑定接收者并实现具体操作;3. invoker触发命令执行;4. receiver执行实际动作;5. client创建命令并设置接收者。例如遥控器(invoker)通过命令控制电灯(receiver)开关。定义命令接口时通常包含execute()虚函数,具体命令如lightoncommand调用接收者的on()方法。若需撤销功能,可在接口添加undo()。调用者remotecontrol保存命令并在按钮按下时执行,支持多按钮可通过map存储不同命令。命令模式优势在于解耦发送者与执行者,适用于事务回滚、任务队列、日志恢复等场景,并可通过组合命令实现宏命令功能。

C++中如何实现命令模式 请求封装与执行解耦的实现方式

在C++中实现命令模式,核心在于将请求封装为对象,从而实现请求的发起者与执行者之间的解耦。这种方式不仅提升了代码的灵活性,还便于实现撤销、重做等操作。

C++中如何实现命令模式 请求封装与执行解耦的实现方式

命令模式的基本结构

命令模式通常由以下几个部分组成:

C++中如何实现命令模式 请求封装与执行解耦的实现方式
  • Command:抽象命令类,定义执行接口。
  • ConcreteCommand:具体命令类,绑定接收者并调用其方法。
  • Invoker:调用者,负责触发命令的执行。
  • Receiver:接收者,真正执行请求的对象。
  • Client:客户端,负责创建命令对象并设置接收者。

举个简单的例子,比如一个遥控器控制电灯开关,遥控器就是调用者,电灯是接收者,而开和关的操作就是具体的命令。

立即学习C++免费学习笔记(深入)”;

如何定义命令接口与具体命令

首先,我们需要定义一个命令接口,通常是带有一个或多个虚函数的抽象类。最常见的是execute()方法。

C++中如何实现命令模式 请求封装与执行解耦的实现方式
class Command {
public:
    virtual void execute() = 0;
    virtual ~Command() = default;
};

接着,定义具体的命令类。例如,一个打开电灯的命令:

class LightOnCommand : public Command {
public:
    explicit LightOnCommand(Light* light) : light_(light) {}

    void execute() override {
        light_->on();
    }

private:
    Light* light_;
};

这里Light是一个“接收者”类,它有具体的on()方法。这样,命令对象就封装了对Light的操作。

注意:如果你需要支持撤销操作,可以在Command类中添加一个undo()虚函数,并在具体命令中实现相应的逻辑。

调用者的实现方式

调用者(Invoker)的作用是保存一个命令对象,并在合适的时候调用它的execute()方法。

问问小宇宙
问问小宇宙

问问小宇宙是小宇宙团队出品的播客AI检索工具

下载

例如,一个简单的遥控器类可以这样写:

class RemoteControl {
public:
    void setCommand(Command* cmd) {
        command_ = cmd;
    }

    void pressButton() {
        if (command_) {
            command_->execute();
        }
    }

private:
    Command* command_ = nullptr;
};

这样,当用户按下按钮时,实际执行的是当前设置的命令。你可以随时更换不同的命令,而无需修改遥控器的逻辑。

这里有个细节需要注意:如果你希望遥控器能支持多个按钮,可以把command_换成一个map,按键编号作为key,对应不同的命令。

命令模式带来的好处与适用场景

命令模式最大的优势在于解耦请求的发送者和执行者,使得它们之间不直接依赖,而是通过命令对象进行通信。

常见应用场景包括:

  • 实现事务回滚或撤销/重做功能(如文本编辑器)
  • 队列任务处理(将命令放入队列中异步执行)
  • 日志记录与恢复(把命令序列化后存储)

此外,命令还可以组合使用,比如宏命令(MacroCommand),它包含多个子命令,在执行时依次调用它们的execute()方法。

class MacroCommand : public Command {
public:
    void addCommand(Command* cmd) {
        commands_.push_back(cmd);
    }

    void execute() override {
        for (auto cmd : commands_) {
            cmd->execute();
        }
    }

private:
    std::vector commands_;
};

这种组合能力让命令模式在构建复杂系统时非常有用。

基本上就这些。只要理解了命令如何封装动作,以及调用者如何与命令交互,就能灵活应用到各种场景中。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

980

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

38

2025.10.17

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

73

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

23

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

36

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

31

2025.11.27

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

115

2025.12.24

拼豆图纸在线生成器
拼豆图纸在线生成器

拼豆图纸生成器有PixelBeads在线版、BeadGen和“豆图快转”;推荐通过pixelbeads.online或搜索“beadgen free online”直达官网,避开需注册的诱导页面。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

84

2025.12.24

俄罗斯搜索引擎yandex官方入口地址(最新版)
俄罗斯搜索引擎yandex官方入口地址(最新版)

Yandex官方入口网址是https://yandex.com。用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

553

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.3万人学习

C 教程
C 教程

共75课时 | 3.7万人学习

C++教程
C++教程

共115课时 | 9.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号