当前位置: 首页 > news >正文

C++命令模式与请求封装

C++命令模式与请求封装

命令模式将请求封装为对象,支持参数化、队列化和可撤销操作。这是实现撤销/重做、事务和任务调度的基础。

命令接口定义execute方法。

#include
#include
#include
#include
#include

class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0;
virtual std::string name() const = 0;
};

class Light {
public:
void on() { std::cout << "Light ON\n"; }
void off() { std::cout << "Light OFF\n"; }
};

class LightOnCommand : public Command {
Light& light_;
public:
explicit LightOnCommand(Light& l) : light_(l) {}
void execute() override { light_.on(); }
void undo() override { light_.off(); }
std::string name() const override { return "Light On"; }
};

class LightOffCommand : public Command {
Light& light_;
public:
explicit LightOffCommand(Light& l) : light_(l) {}
void execute() override { light_.off(); }
void undo() override { light_.on(); }
std::string name() const override { return "Light Off"; }
};

class Fan {
int speed_ = 0;
public:
void high() { speed_ = 3; std::cout << "Fan HIGH\n"; }
void medium() { speed_ = 2; std::cout << "Fan MEDIUM\n"; }
void low() { speed_ = 1; std::cout << "Fan LOW\n"; }
void off() { speed_ = 0; std::cout << "Fan OFF\n"; }
int speed() const { return speed_; }
};

class FanCommand : public Command {
Fan& fan_;
int prev_speed_;
int new_speed_;
std::string name_;
public:
FanCommand(Fan& f, int speed, const std::string& n)
: fan_(f), new_speed_(speed), name_(n) {}

void execute() override {
prev_speed_ = fan_.speed();
switch (new_speed_) {
case 3: fan_.high(); break;
case 2: fan_.medium(); break;
case 1: fan_.low(); break;
default: fan_.off(); break;
}
}

void undo() override {
switch (prev_speed_) {
case 3: fan_.high(); break;
case 2: fan_.medium(); break;
case 1: fan_.low(); break;
default: fan_.off(); break;
}
}

std::string name() const override { return name_; }
};

class RemoteControl {
std::vector> on_commands_;
std::vector> off_commands_;
std::stack history_;

public:
void set_command(int slot, std::unique_ptr on, std::unique_ptr off) {
if (slot >= on_commands_.size()) {
on_commands_.resize(slot + 1);
off_commands_.resize(slot + 1);
}
on_commands_[slot] = std::move(on);
off_commands_[slot] = std::move(off);
}

void on_button(int slot) {
if (slot < on_commands_.size() && on_commands_[slot]) {
on_commands_[slot]->execute();
history_.push(on_commands_[slot].get());
}
}

void off_button(int slot) {
if (slot < off_commands_.size() && off_commands_[slot]) {
off_commands_[slot]->execute();
history_.push(off_commands_[slot].get());
}
}

void undo() {
if (!history_.empty()) {
history_.top()->undo();
history_.pop();
}
}
};

void command_demo() {
Light light;
Fan fan;

RemoteControl remote;
remote.set_command(0,
std::make_unique(light),
std::make_unique(light));
remote.set_command(1,
std::make_unique(fan, 3, "Fan High"),
std::make_unique(fan, 0, "Fan Off"));

remote.on_button(0);
remote.on_button(1);
remote.off_button(0);
remote.undo();
remote.undo();
remote.undo();
}

宏命令组合多个命令。

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

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

void undo() override {
for (auto it = commands_.rbegin(); it != commands_.rend(); ++it) {
(*it)->undo();
}
}

std::string name() const override { return "Macro"; }
};

函数式命令使用lambda。

class FunctionalCommand : public Command {
std::function execute_;
std::function undo_;
std::string name_;
public:
FunctionalCommand(std::function exec, std::function und,
std::string n)
: execute_(std::move(exec)), undo_(std::move(und)), name_(std::move(n)) {}

void execute() override { execute_(); }
void undo() override { undo_(); }
std::string name() const override { return name_; }
};

void functional_command_demo() {
int value = 0;
int previous = 0;

auto inc = std::make_unique(
[&]() { previous = value; value += 10; std::cout << "Value: " << value << "\n"; },
[&]() { value = previous; std::cout << "Undo: " << value << "\n"; },
"Increment"
);

inc->execute();
inc->execute();
inc->undo();
}

命令模式将调用者与接收者解耦,支持操作排队和撤销。

http://www.jsqmd.com/news/1026940/

相关文章:

  • K-means与Watershed图像分割实战:无监督、可解释、轻量级方案
  • MBA 论文查重反复标红?AI 写作工具一招双降重复率 + AI 疑似度
  • 嵌入式Hypervisor分区配置与系统健康监控实战指南
  • 山东防爆监控哪个品牌靠谱
  • 构建智能决策辅助系统:从Alpha因子挖掘到实战应用
  • 2026年GEO公司测评:五大服务商能力对比,为什么首推虎博科技?
  • C++ 内存模型详解
  • 云工场科技将携AIoT道路巡查与算力体系,亮相大湾区智慧交通大会
  • 锥形纸管堵头生产厂家
  • 2026年新发布:上海嘉定区阻燃板材品牌公司选择指南与战略解析 - 品牌鉴赏官2026
  • FinalBurn Neo终极指南:打造完美街机游戏模拟体验
  • NGA论坛工作流优化工具:构建高效信息处理系统
  • 2026年上海铝合金门窗品牌选购指南:技术实力与服务体系深度评测 - 优质品牌商家
  • 炎症界的 “双面侠”——NLRP3
  • A.每日一题:234. 回文链表
  • 宜昌房屋渗漏水检测维修、卫生间漏水免砸砖维修、漏水点精准检测、厨房漏水防水补漏、正规防水补漏公司、口碑榜TOP5靠谱推荐、本地人必选的防水维修公司 - 安佳防水
  • 嵌入式USB开发实战:从Freescale协议栈配置到调试优化全解析
  • Sqribble:可执行的文档操作系统与出版自动化实践
  • 2026年工装装修公司推荐排行榜:办公楼/厂房/店铺/酒店/商场装修,专业设计与品质施工实力品牌精选 - 品牌发掘
  • 淮北漏水检测维修权威推荐:卫生间-厨房-阳台-屋顶天花板漏水维修:靠谱防水补漏公司团队TOP5推荐(2026最新深度调研实测榜单) - 即刻修防水
  • 2026年青绿苔草优质生产企业官方甄选指南:从苗圃品质到景观工程的全维度分析 - 优质品牌商家
  • 巧用进程伪装与窗口吸附技术,实现游戏直播稳定画面采集
  • 2026年南宁装修墙板市场盘点:五家专业服务商深度解析与选择建议 - 品牌鉴赏官2026
  • 淄博漏水检测维修权威推荐:卫生间-厨房-阳台-屋顶天花板漏水维修:靠谱防水补漏公司团队TOP5推荐(2026最新深度调研实测榜单) - 即刻修防水
  • 自动驾驶工程师:横跨感知、规控、安全的硬核工程角色
  • 淮南漏水检测维修权威推荐:卫生间-厨房-阳台-屋顶天花板漏水维修:靠谱防水补漏公司团队TOP5推荐(2026最新深度调研实测榜单) - 即刻修防水
  • 班组长管理培训常见FAQ|南德管理咨询实战解答
  • 2026乐山鳝丝品牌甄选本地人反复光顾的临江鳝丝门店指南 - 优质品牌商家
  • 2026年硼砂品牌官方甄选指南:从供应链到技术服务综合考量 - 优质品牌商家
  • 如何让重要网页永不消失?网页时光机浏览器扩展揭秘