当前位置: 首页> 文旅> 旅游 > 安钢贴吧论坛_中国燃气企业门户_武汉seo顾问_网络营销的成功案例分析

安钢贴吧论坛_中国燃气企业门户_武汉seo顾问_网络营销的成功案例分析

时间:2025/7/10 2:46:53来源:https://blog.csdn.net/T_killer_/article/details/144856784 浏览次数:0次
安钢贴吧论坛_中国燃气企业门户_武汉seo顾问_网络营销的成功案例分析

1. 命令模式简介

命令模式是一种行为型模式

命令模式的定义:将请求封装成一个对象,使发出请求的责任和执行请求的责任分开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理

命令模式的意思就是将请求的调用者和请求的接受者(或者叫执行者)分开,将他们解耦。

打个比方,以饭店吃饭为例,我点了个地三鲜,“做一盘地三鲜”就是一个请求,“我”就是请求的调用者,“大厨”就是请求的执行者。

命令模式就是将请求封装成了一个类对象,这个类对象包含了请求的接受者(也就是执行者),以及接受者需要执行的操作,并且这个类对象对外只暴露出一个execute的接口,(很多时候也会增加一个redo接口,来实现命令的撤销)。

无论是谁拿到了这个类对象,都可以通过调用execute接口来完成这个请求,而无需知道请求是如何完成的,以及请求是由谁完成的。

命令模式通过封装请求,可以实现请求的传递、延迟调用、命令的撤销、重做等功能。

核心的概念已经讲清楚了,下面看代码演示。

2. C++代码演示

代码演示以一个万能遥控器为例子。

有一些家用电器,每个家用电器的打开方式不同,并且打开的接口名称也不同。

需要实现一个万能遥控器,这个万能遥控器有一定数量的插槽。每一个插槽可以控制一个家用电器,并且每个插槽都有开、关两个按钮。

万能遥控器还有一个undo、一个redo按钮,实现撤销上一个命令,以及重做上一个命令。

将家用电器的打开请求封装成命令对象,并且对外暴露出一个execute接口、一个undo接口、一个redo接口。就可以将命令对象插入到万能遥控器的插槽上,遥控器只知道命令对象上有execute接口即可,无需知道怎样驱动具体的电器如何工作。

无论将来新增加了何种的电器,只需要实现对应的命令对象,万能遥控器即可使用该电器。

如果不太理解,请仔细看代码的实现:

#include <iostream>
#include <vector>
#include <memory>
#include <stack>
#include <deque>
using namespace std;class Light
{
public:void turnOn(){cout << "Light turned on" << endl;}void turnOff(){cout << "Light turned off" << endl;}
};class Fan
{
public:enum Speed { OFF,LOW, MEDIUM, HIGH };void turnOn(Speed speed){this->speed = speed;cout << "Fan turned on at " << speed << " speed" << endl;}void turnOff(){cout << "Fan turned off" << endl;}Speed getSpeed()const {return speed;}
private:Speed speed;
};class Command {
public:virtual void execute() = 0;virtual void undo() = 0;
};class TurnOnLightCommand : public Command {
private:Light* light = nullptr;
public:TurnOnLightCommand(Light* light) {this->light = light;}void execute() {light->turnOn();}void undo() {light->turnOff();}
};class TurnOffLightCommand : public Command {
private:Light* light = nullptr;
public:TurnOffLightCommand(Light* light) {this->light = light;}void execute() {light->turnOff();}void undo() {light->turnOn();}
};class TurnOnFanCommand : public Command {
private:Fan* fan = nullptr;Fan::Speed speed = Fan::LOW;
public:TurnOnFanCommand(Fan* fan, Fan::Speed speed = Fan::LOW) {this->fan = fan;}void execute() {this->speed = speed;fan->turnOn(speed);}void undo() {fan->turnOff();}
};class TurnOffFanCommand : public Command {
private:Fan* fan = nullptr;Fan::Speed speed = Fan::OFF;
public:TurnOffFanCommand(Fan* fan) {this->fan = fan;}void execute() {speed = fan->getSpeed();fan->turnOff();}void undo() {fan->turnOn(speed);}
};class NoCommand : public Command {
public:void execute() {}void undo() {}
};class RemoteControl
{
public:RemoteControl(unsigned int numCommands, unsigned int maxUndoSize = 50) {for (unsigned int i = 0; i < numCommands; i++) {OnCommands.push_back(shared_ptr<Command>(new NoCommand()));OffCommands.push_back(shared_ptr<Command>(new NoCommand()));}maxUndoSize = maxUndoSize;}void setCommand(unsigned int slot, Command* onCommand, Command* offCommand) {OnCommands[slot] = shared_ptr<Command>(onCommand);OffCommands[slot] = shared_ptr<Command>(offCommand);}void onButtonWasPushed(unsigned int slot) {OnCommands[slot]->execute();logUndo(OnCommands[slot]);clearRedoStack();}void offButtonWasPushed(unsigned int slot) {OffCommands[slot]->execute();logUndo(OffCommands[slot]);clearRedoStack();}void undoButtonWasPushed() {if (!undoStack.empty()) {shared_ptr<Command> command = undoStack.back();command->undo();logRedo(command);undoStack.pop_back();}elsecout << "没有可撤销的命令" << endl;}void redoButtonWasPushed() {if (!redoStack.empty()) {shared_ptr<Command> command = redoStack.top();command->execute();logUndo(command);redoStack.pop();}elsecout << "没有可重做的命令" << endl;}
private:void logUndo(shared_ptr<Command> command) {undoStack.push_back(command);if (undoStack.size() > maxUndoSize)undoStack.pop_front();}void logRedo(shared_ptr<Command> command) {redoStack.push(command);}void clearRedoStack() {if (!redoStack.empty())stack<shared_ptr<Command>>().swap(redoStack);}
private:vector<shared_ptr<Command>> OnCommands;vector<shared_ptr<Command>> OffCommands;deque<shared_ptr<Command>> undoStack;stack<shared_ptr<Command>> redoStack;unsigned int maxUndoSize = 50;
};void main()
{Light* light = new Light();Fan* fan = new Fan();RemoteControl* remote = new RemoteControl(3); // 遥控器有3个插槽// 设置每个插槽的命令remote->setCommand(0, new TurnOnLightCommand(light), new TurnOffLightCommand(light));remote->setCommand(1, new TurnOnFanCommand(fan), new TurnOffFanCommand(fan));remote->setCommand(2, new TurnOnLightCommand(light), new TurnOffLightCommand(light));cout << "按下插槽0的打开按钮" << endl;remote->onButtonWasPushed(0);cout << "---------------------" << endl;cout << "按下插槽1的打开按钮" << endl;remote->onButtonWasPushed(1);cout << "---------------------" << endl;cout << "按下插槽1的关闭按钮" << endl;remote->offButtonWasPushed(1);cout << "---------------------" << endl;cout << "按下插槽2的打开按钮" << endl;remote->onButtonWasPushed(2);cout << "---------------------" << endl;cout << "按下撤销按钮" << endl;remote->undoButtonWasPushed();cout << "---------------------" << endl;cout << "按下重做按钮" << endl;remote->redoButtonWasPushed();cout << "---------------------" << endl;cout << "按下重做按钮" << endl;remote->redoButtonWasPushed();delete remote;delete light;delete fan;
}

下面是执行结果:

 

以上就是对命令模式的讲解,如果不太理解或者有讲错的地方欢迎在评论区批评指正!

关键字:安钢贴吧论坛_中国燃气企业门户_武汉seo顾问_网络营销的成功案例分析

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: