跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 命令模式实现
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++命令模式实现 = 命令模式(Command Pattern)是一种行为设计模式,它将请求或操作封装为独立的对象,从而使你可以参数化客户端与不同的请求、队列或日志请求,并支持可撤销的操作。在C++中,命令模式常用于实现回调机制、任务队列或撤销/重做功能。 == 介绍 == 命令模式的核心思想是将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化。这种模式的主要组成部分包括: * '''命令接口(Command)''':声明执行操作的接口。 * '''具体命令(ConcreteCommand)''':实现命令接口,绑定接收者与动作。 * '''接收者(Receiver)''':知道如何执行与请求相关的操作。 * '''调用者(Invoker)''':触发命令对象执行请求。 * '''客户端(Client)''':创建具体的命令对象并设置其接收者。 命令模式的主要优点包括: * 解耦调用操作的对象与知道如何实现操作的对象。 * 支持撤销和重做操作。 * 支持将命令组合成复合命令(宏命令)。 == 代码示例 == 以下是一个简单的C++实现示例,展示如何使用命令模式控制电器的开关: <syntaxhighlight lang="cpp"> #include <iostream> #include <memory> #include <vector> // 接收者类:电器 class ElectronicDevice { public: void turnOn() { std::cout << "Device is ON" << std::endl; } void turnOff() { std::cout << "Device is OFF" << std::endl; } }; // 命令接口 class Command { public: virtual ~Command() = default; virtual void execute() = 0; }; // 具体命令:打开电器 class TurnOnCommand : public Command { ElectronicDevice& device; public: explicit TurnOnCommand(ElectronicDevice& dev) : device(dev) {} void execute() override { device.turnOn(); } }; // 具体命令:关闭电器 class TurnOffCommand : public Command { ElectronicDevice& device; public: explicit TurnOffCommand(ElectronicDevice& dev) : device(dev) {} void execute() override { device.turnOff(); } }; // 调用者:遥控器 class RemoteControl { std::vector<std::unique_ptr<Command>> commands; public: void addCommand(std::unique_ptr<Command> cmd) { commands.push_back(std::move(cmd)); } void pressButton(int index) { if (index >= 0 && index < commands.size()) { commands[index]->execute(); } } }; int main() { ElectronicDevice tv; RemoteControl remote; // 设置命令 remote.addCommand(std::make_unique<TurnOnCommand>(tv)); remote.addCommand(std::make_unique<TurnOffCommand>(tv)); // 执行命令 remote.pressButton(0); // 输出: Device is ON remote.pressButton(1); // 输出: Device is OFF return 0; } </syntaxhighlight> === 输出 === <pre> Device is ON Device is OFF </pre> == 类图 == 以下是用mermaid绘制的命令模式类图: <mermaid> classDiagram class Command { <<interface>> +execute() } class ConcreteCommandA { -receiver: Receiver +execute() } class ConcreteCommandB { -receiver: Receiver +execute() } class Receiver { +action() } class Invoker { -command: Command +setCommand() +executeCommand() } class Client Command <|-- ConcreteCommandA Command <|-- ConcreteCommandB ConcreteCommandA --> Receiver ConcreteCommandB --> Receiver Invoker o-- Command Client ..> ConcreteCommandA Client ..> ConcreteCommandB Client ..> Receiver Client ..> Invoker </mermaid> == 实际应用场景 == 命令模式在以下场景中特别有用: 1. '''GUI按钮和菜单项''':每个按钮点击或菜单选择可以绑定到不同的命令对象。 2. '''事务系统''':每个操作可以封装为命令,支持撤销和重做。 3. '''任务调度''':将任务封装为命令对象,放入队列中按顺序执行。 4. '''宏录制''':将多个命令组合成一个复合命令。 === 高级应用:支持撤销 === 扩展前面的例子,添加撤销功能: <syntaxhighlight lang="cpp"> // 扩展命令接口支持撤销 class UndoableCommand : public Command { public: virtual void undo() = 0; }; // 具体命令:带撤销的开关命令 class ToggleCommand : public UndoableCommand { ElectronicDevice& device; bool wasOn = false; public: explicit ToggleCommand(ElectronicDevice& dev) : device(dev) {} void execute() override { wasOn = !wasOn; if (wasOn) device.turnOn(); else device.turnOff(); } void undo() override { wasOn = !wasOn; if (wasOn) device.turnOn(); else device.turnOff(); } }; // 扩展调用者支持撤销 class AdvancedRemoteControl { std::vector<std::unique_ptr<UndoableCommand>> commands; std::vector<std::unique_ptr<UndoableCommand>> history; public: void addCommand(std::unique_ptr<UndoableCommand> cmd) { commands.push_back(std::move(cmd)); } void pressButton(int index) { if (index >= 0 && index < commands.size()) { commands[index]->execute(); history.push_back(std::move(commands[index])); commands.erase(commands.begin() + index); } } void undoLast() { if (!history.empty()) { history.back()->undo(); history.pop_back(); } } }; </syntaxhighlight> == 数学表示 == 命令模式可以形式化表示为: <math> \begin{cases} Command \equiv execute() \\ ConcreteCommand \equiv execute() = receiver.action() \\ Invoker \equiv setCommand(c: Command), executeCommand() = c.execute() \end{cases} </math> == 总结 == 命令模式在C++中提供了一种灵活的方式来封装操作请求,使系统更易于扩展和维护。通过将请求封装为对象,你可以: * 参数化对象与不同请求 * 支持队列请求 * 实现撤销/重做功能 * 构建复合命令(宏命令) 这种模式特别适合需要解耦发送者和接收者、或者需要支持事务性操作的场景。对于C++开发者来说,结合智能指针和现代C++特性可以创建更安全、更高效的命令模式实现。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 设计模式]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)