命令模式:将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销操作。
命令模式将发出请求的对象和执行请求的对象解耦,被解耦的对象是通过命令对象进行沟通的。命令对象封装了接收者一个或一组的动作。撤销的实现是实现一个undo函数来回到execute之前的状态(多次撤销可以用堆栈来存储状态)。命令模式也能来实现日志和事务系统。
日志的应用:
日志系统需要我们将所有的动作都记录在日志中,并且能在系统死机过后,重新调度这些动作来恢复到之前的状态。通过新增两个方法(store、load),命令模式就可以支持日志应用。
代码:
Command.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class Barbecuer
{
public:
void BakeOne() { cout << "BakeOne" << endl; }
void BakeSec() { cout << "BakeSec" << endl; }
};
class Command
{
public:
Command(Barbecuer* pp):p(pp){}
virtual void execute() = 0;
protected:
Barbecuer* p;
};
class BakeOne :public Command
{
public:
BakeOne(Barbecuer* pp):Command(pp) { p = pp; }
void execute() {
p->BakeOne();
}
};
class BakeSec :public Command
{
public:
BakeSec(Barbecuer* pp) :Command(pp) { p = pp; }
void execute() {
p->BakeSec();
}
};
class Waiter {
public:
void Order(Command* pp) { List.push_back(pp); }
void Notify() {
vector<Command*>::iterator iter;
for (iter = List.begin(); iter != List.end(); iter++)
{
(*iter)->execute();
}
}
private:
vector<Command*> List;
};
**
Command.cpp
**
#include <iostream>
#include "Command.h"
using namespace std;
int main()
{
Barbecuer* p=new Barbecuer;
BakeOne* b1 = new BakeOne(p);
BakeSec* b2=new BakeSec(p);
Waiter* w=new Waiter;
w->Order(b2);
w->Order(b1);
w->Notify();
delete b1;
delete b2;
}