将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
2. 动机
有时必须向某对象提交请求,但并不知道关于被请求的操作或请求的接受者的任何信息。例如,用户界面工具箱包括按钮和菜单这样的对象,它们执行请求响应用户输入。但工具箱不能显式的在按钮或菜单中实现该请求,因为只有使用工具箱的应用知道该由哪个对象做哪个操作。而工具箱的设计者无法知道请求的接受者或执行的操作。命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。这个对象可被存储并像其他的对象一样被传递。这一模式的关键是一个抽象的C o m m a n d类,它定义了一个执行操作的接口。其最简单的形式是一个抽象的E x e c u t e操作。具体的C o m m a n d子类将接收者作为其一个实例变量,并实现E x e c u t e操作,指定接收者采取的动作。而接收者有执行该请求所需的具体信息。
3. 模式中角色
3.1 抽象命令(Command):定义命令的接口,声明执行的方法。
3.2 具体命令(ConcreteCommand):具体命令,实现要执行的方法,它通常是“虚”的实现;通常会有接收者,并调用接收者的功能来完成命令要执行的操作。
3.3 接收者(Receiver):真正执行命令的对象。任何类都可能成为一个接收者,只要能实现命令要求实现的相应功能。
3.4 调用者(Invoker):要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
3.5 客户端(Client):命令由客户端来创建,并设置命令的接收者。
4.UML类图
5.C++代码:
#ifndef COMMAND_H
#define COMMAND_H
#include <iostream>
using std::cout;
using std::endl;
class CReceiver{
public:
virtual void eat()=0;
virtual void sleep()=0;
};
class CCatReceiver : public CReceiver{
public:
virtual void eat(){
cout<<"Cat is eating!"<<endl;
}
virtual void sleep(){
cout<<"Cat is sleeping!"<<endl;
}
};
class CDogReceiver : public CReceiver{
public:
virtual void eat(){
cout<<"Dog is eating!"<<endl;
}
virtual void sleep(){
cout<<"Dog is sleeping!"<<endl;
}
};
class CCommand{
public:
virtual void Execute()=0;
};
class CConcreateCommandA : public CCommand{
private:
CReceiver* pReceiver;
public:
CConcreateCommandA(CReceiver* temp): pReceiver(temp){}
virtual void Execute(){
cout<<"Executing the Concreate Command A!"<<endl;
pReceiver->eat();
}
};
class CConcreateCommandB : public CCommand{
private:
CReceiver* pReceiver;
public:
CConcreateCommandB(CReceiver* temp): pReceiver(temp){}
virtual void Execute(){
cout<<"Executing the Concreate Command B!"<<endl;
pReceiver->sleep();
}
};
class CInvoker{
private:
CCommand* pCommand;
public:
void SetCommand(CCommand* temp){
pCommand=temp;
}
void ExcuteCommand(){
pCommand->Execute();
}
};
#endif
#include "command.h"
int main(){
CInvoker* pInvoker=new CInvoker;
CCommand* pCommand=new CConcreateCommandA(new CCatReceiver);
pInvoker->SetCommand(pCommand);
pInvoker->ExcuteCommand();
pCommand=new CConcreateCommandB(new CDogReceiver);
pInvoker->SetCommand(pCommand);
pInvoker->ExcuteCommand();
return 0;
}