1、意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2、动机
有时候必须向某个对象提交请求,但并不知道关于被请求的操作或者请求的接受者的任何信息。例如,用户界面工具箱包括按钮和菜单这样的对象,它们执行请求响应用户输入。但工具箱不能显式的在按钮或菜单中实现该请求,因为只有使用工具箱的应用知道该由那个对象做那个操作。而工具箱的设计者无法知道请求的接受者或执行的操作。
3、适用性
1)抽象出待执行的动作以参数化某对象。你可用过程语言中的回调(callback)函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。Command模式是回调机制的一个面向对象的替代品。
2)在不同的时刻指定、排列和执行请求。一个Command对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
3)支持取消操作。Command的Excute操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。Command接口必须添加一个Unexecute操作,该操作取消上一次Excute调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”;
4)支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
5)用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务(transaction)的信息系统中很常见。一个事务封装了对数据的一组变动。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用一种方式调动所有的事务。同时使用该模式也易于添加新事务以扩展系统。
4、C++实例
1)callback模式
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <list>
using namespace std;
class Command
{
public:
virtual ~Command()
{
}
virtual void Execute() = 0;
protected:
Command()
{
}
};
template <class Receiver>
class SimpleCommand: public Command
{
public:
typedef void (Receiver::* Action) ();
SimpleCommand( Receiver *r, Action a ):
_receiver(r), _action( a ) { }
virtual void Execute();
private:
Action _action;
Receiver* _receiver;
};
template <class Receiver>
void SimpleCommand<Receiver>::Execute()
{
(_receiver->*_action)();
}
class Myclass
{
public:
Myclass()
{
}
virtual ~Myclass()
{
}
public:
void Action()
{
cout<<"Myclass::Action"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Myclass *receiver = new Myclass;
Command *aCommand = new SimpleCommand<Myclass>( receiver, &Myclass::Action );
aCommand->Execute();
delete aCommand;
delete receiver;
return 0;
}
2)状态类模式
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef int BOOL;
#define FALSE 0
#define TRUE 1
class CWork;
class CState
{
public:
virtual void WriteProgram(CWork* work){};
};
class CForenoonState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CNoonState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CAfternoonState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CEveningState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CSleepingState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CRestState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CCommandState:public CState
{
public:
virtual void WriteProgram(CWork* work);
};
class CWork
{
public:
CState* m_state;
BOOL m_finish;
BOOL m_comand;//强制下班命令
void Setcomand(BOOL comand)
{
m_comand=comand;
}
double Getcomand()
{
return m_comand;
}
public:
CWork()
{
m_state=new CForenoonState();
m_finish=FALSE;
m_comand=FALSE;
}
public:
double m_hour;
void SetHour(double hour)
{
m_hour=hour;
}
double GetHour()
{
return m_hour;
}
void SetFinished(BOOL finished)
{
m_finish=finished;
}
BOOL GetFinished()
{
return m_finish;
}
void SetState(CState* state)
{
m_state=state;
}
void WriteProgram()
{
m_state->WriteProgram(this);
}
};
void CForenoonState::WriteProgram(CWork *work)
{
if (work->m_hour<12)
{
cout<<"当前时间:"<<work->m_hour<<" 点 上午工作,精神百倍"<<endl;
}
else
{
work->SetState(new CNoonState());
work->WriteProgram();
}
}
void CNoonState::WriteProgram(CWork *work)
{
if (work->m_hour<13)
{
cout<<"当前时间: "<<work->m_hour<<"点 饿了,午饭;犯困,午休"<<endl;
}
else
{
work->SetState(new CAfternoonState());
work->WriteProgram();
}
}
void CAfternoonState::WriteProgram(CWork *work)
{
if (work->m_hour<17)
{
cout<<"当前时间: "<<work->m_hour<<"点 下午状态还不错,继续努力"<<endl;
}
else
{
work->SetState(new CEveningState());
work->WriteProgram();
}
}
void CEveningState::WriteProgram(CWork *work)
{
if (work->m_finish)
{
work->SetState(new CRestState());
work->WriteProgram();
}
else
{
if (work->m_hour>20&&work->m_comand)
{
work->SetState(new CCommandState());
work->WriteProgram();
return;
}
if (work->m_hour<21)
{
cout<<"当前时间:"<<work->m_hour<<"点 加班哦,疲累之极"<<endl;
}
else
{
work->SetState(new CSleepingState());
work->WriteProgram();
}
}
}
void CSleepingState::WriteProgram(CWork *work)
{
cout<<"当前时间: "<<work->m_hour<<"点不行了,睡着了"<<endl;
}
void CRestState::WriteProgram(CWork* work)
{
cout<<"当前时间:"<<work->m_hour<<"点下班回家了"<<endl;
}
void CCommandState::WriteProgram(CWork *work)
{
cout<<"员工必须在20点之前离开公司"<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
CWork* pWork=new CWork();
pWork->SetHour( 9 );
pWork->WriteProgram();
pWork->Setcomand(TRUE);
pWork->SetHour(20.1);
/*pWork->SetFinished(TRUE);*/
pWork->WriteProgram();
delete pWork;
return 0;
}