命令模式,是將一個請求封裝為一個對象,從而使我們可以用不同的請求對客戶進(jìn)行參數(shù)化、對請求排隊或記錄請求日志,以及支持可撤銷的操作。
命令模式結(jié)構(gòu)圖
image
命令模式基本代碼
#include <iostream>
#include <list>
using namespace std;
// Receiver類,知道如何實施與執(zhí)行一個與請求相關(guān)的操作:
class Receiver {
public:
void Action() {
cout << "Receiver" << endl;
}
};
// Command類,用來聲明執(zhí)行操作的接口
class Command {
public:
virtual void Excute() = 0;
virtual void setReceiver(Receiver* r) = 0;
virtual ~Command(){};
};
// ConcreteCommand類,綁定一個Receiver,調(diào)用其相應(yīng)操作以實現(xiàn)Excute:
class ConcreteCommand : public Command {
private:
Receiver* receiver;
public:
void setReceiver(Receiver* r) {
receiver = r;
}
void Excute() {
//cout << "ConcreteCommand" << endl;
receiver->Action();
}
};
// 要求該命令執(zhí)行這個請求:
class Invoker {
private:
list<Command* > commands;
public:
void setCommand(Command* c) {
commands.push_back(c);
}
void Notify() {
for (auto c = commands.begin(); c != commands.end(); c++) {
(*c)->Excute();
}
}
};
// 客戶端實現(xiàn)代碼:
int main() {
Command* c = new ConcreteCommand();
Receiver* r = new Receiver();
c->setReceiver(r);
Invoker I;
i.setCommand(c);
i.Notify(); // Receiver
delete r;
delete c;
return 0;
}
應(yīng)用場景
優(yōu)點:
- 能較容易地設(shè)計一個命令隊列;
- 在需要的情況下,可以較容易地將命令記入日志;
- 允許接收請求的一方?jīng)Q定是否要否決請求;
- 可以輕易地實現(xiàn)對請求的撤銷和重做;
- 增加新的具體命令類很方便;
- 命令模式把請求一個操作的對象與知道怎么執(zhí)行一個操作的對象分割開了。