Command Pattern:
Encapsulates a request as an object, thereby letting you parametrize other objects with different requests, queue or log requests, and support undo-able operations.
Command Pattern is usually used in the scenario that we want to perform multiple operations on the same data. For example, in a image processor, we could choose to rotate, flip or invert colors of the photo or even to undo the operations. It also allows to decouple the requester from an action from the object that actually performs the action.
Example without using Command Pattern:
class imageProcess {
private:
bool rotateImage;
bool flipImage;
bool deleteImage;
public:
void inputHandler() {
if(rotateImage) {rotate();}
else if(flipImage) {flipImage();}
else if(deleteImage) {deleteImage();}
}
};The drawback is quite clear: we will have to write a lot of condition code for each action. Also, if we have more commands, we will have to change the existing code very often. To solve this problem, there is a mechanism that
all the actions can somehow be handled polymorphically which makes the code clean and less error prone. This isCommand Pattern.
1: Allows to store a lists of code that is executed at a later time or many times.
2: Client says that a specific Command to run when execute() is called on one of the encapsulated objects. (dynamic binding)
3: An object called the "Invoker" transfers this Command to another Object called a "Receiver" to execute the right code.
For example:
TurnTVOn --> Device Botton(invoker) --> TurnTVOn --> Television.TurnTVOn() (receiver)
#include "../header.h"
using namespace std;
class Command {
public:
virtual void execute() = 0;
};
class ElectronicDevice {
public:
virtual void on() = 0;
virtual void off() = 0;
virtual void volumnUp() = 0;
virtual void volumnDown() = 0;
};
class TurnTvOn : public Command {
private:
ElectronicDevice* newDevice;
public:
TurnTvOn(ElectronicDevice* device) {
newDevice = device;
}
void execute() {
newDevice->on();
}
};
class VolumnUp : public Command {
private:
ElectronicDevice* newDevice;
public:
VolumnUp(ElectronicDevice* device) {
newDevice = device;
}
void execute() {
newDevice->volumnUp();
}
};
// this is the invoker.
class DeviceButton {
private:
Command* theCommand;
public:
DeviceButton(Command* newCommand) {
theCommand = newCommand;
}
void press() {
theCommand->execute();
}
};
// this is the receiver
class Television : public ElectronicDevice {
private:
int volumn;
public:
Television(int v) : volumn(v) {}
void on() {
cout << "TV is ON" << endl;
}
void off() {
cout << "TV is OFF" << endl;
}
void volumnUp() {
volumn++;
cout << "volumn is at: " << volumn << endl;
}
void volumnDown() {
volumn--;
cout << "volumn is at: " << volumn << endl;
}
};
//test
int main(void) {
int volumn = 0;
ElectronicDevice* device = new Television(volumn);
TurnTvOn* onCommand = new TurnTvOn(device);
DeviceButton* onPressed = new DeviceButton(onCommand);
onPressed->press();
VolumnUp* volumnCommand = new VolumnUp(device);
onPressed = new DeviceButton(volumnCommand);
onPressed->press();
}
本文介绍命令模式设计的基本原理,通过实例展示如何将请求封装为对象,实现参数化操作及支持撤销功能。文章还探讨了该模式如何解耦请求发起者与执行者,使代码更加灵活且易于维护。
141

被折叠的 条评论
为什么被折叠?



