命令模式:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
说白了,就是不去直接指挥别人去干啥干啥,而是记录好你的命令,然后再去指挥对应的人去执行你的任务,由于命令记录好了,那么撤销、排队什么的操作就可行了。
总结下优点:
能较容易的设计一个命令队列。
在需要的情况下,可以较容易的将命令记录日志
允许接收请求的一方决定是否执行请求。
可以容易的实现对请求的撤销和重做。
由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
虽然有这么多优点,但是也不是碰到类似情况就一定要实现命令模式。
敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要去着急实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能是,把原来的代码重构为命令模式才有意义。
书上的图(《大话设计模式》):
使用c++实现它:
#include <iostream>
#include <string>
using namespace std;
class Receiver;
//声明执行操作的接口
class Command
{
protected:
Receiver *receiver;
public:
Command(Receiver *_rec):receiver(_rec) {}
virtual ~Command() = 0 {}
virtual void Execute() = 0;
};
//将一个接收者对象绑定于一个动作,execute调用接收者相应的操作
class ConcreteCommand :public Command
{
public:
ConcreteCommand(Receiver *_rec) :Command(_rec)
{}
~ConcreteCommand() {}
virtual void Execute();
};
//要求命令执行的类
class Invoker
{
private:
Command* comm;
public:
Invoker(Command* _com):comm(_com) {}
~Invoker() {}
void ExecuteCommand()
{
comm->Execute();
}
};
//实际执行一个请求的类
class Receiver
{
public:
Receiver() {}
~Receiver() {}
void Action()
{
cout << "执行请求" << endl;
}
};
void ConcreteCommand::Execute()
{
receiver->Action();
}
int main()
{
Receiver *r = new Receiver();
Command *c = new ConcreteCommand(r);
Invoker *i = new Invoker(c);
i->ExecuteCommand();
getchar();
return 0;
}
实际上,Command类把receiver成员换成一个list,然后加上add和del接口,就可以实现一个任务队列,还可以撤销,可以重做,随时添加删除任务,这里就不写了。懒