什么是命令模式?
GoF的书的定义为:“Command pattern encapsulate request as an object, thereby letting you parameterize clients with different request, queue or log request, and support undoable operations”
换言之,讲命令封装成一个对象,既有状态也能执行动作,发出命令者不需要知道命令最终是谁执行的,如何执行,它只依赖抽象。而且调用者可以根据命令纪录,维护一个命令队列,或者log所有的命令。命令模式也可以方便的实现撤销操作。
类图结构:![Command_Design_Pattern_Class_Diagram.png](http://upload.wikimedia.org/wikipedia/commons/8/8e/Command_Design_Pattern_Class_Diagram.png)
Example:
例子模拟游戏里给人发出移动和跳的命令,Player对应于类图里面的Receiver,代码如下。
#include <iostream>
using namespace std;
class Player
{
public:
void move(int x, int y)
{
cout << "player move to (" << x << ", " << y << ")" << endl;
}
void jump()
{
cout << "player jump" << endl;
}
};
class Command
{
public:
virtual void execute() = 0;
};
class MoveCommand : public Command
{
public:
MoveCommand(Player* pPlayer, int x, int y)
: m_pPlayer(pPlayer), m_intX(x), m_intY(y) { }
virtual void execute()
{
if (m_pPlayer)
m_pPlayer->move(m_intX, m_intY);
}
private:
Player* m_pPlayer;
int m_intX, m_intY;
};
class JumpCommand : public Command
{
public:
JumpCommand(Player* pPlayer) : m_pPlayer(pPlayer) {}
virtual void execute()
{
if (m_pPlayer)
m_pPlayer->jump();
}
private:
Player* m_pPlayer;
};
class Invoker
{
public:
void takeOrder(Command* pCommand)
{
pCommand->execute();
delete pCommand;
}
};
int main()
{
Player* pPlayer = new Player();
Invoker invoker;
char orderType;
while (cin >> orderType)
{
int x, y;
if (orderType == 'm' && cin >> x >> y)
invoker.takeOrder(new MoveCommand(pPlayer, x, y));
else if (orderType == 'j')
invoker.takeOrder(new JumpCommand(pPlayer));
}
delete pPlayer;
return 0;
}
可以对Invoker修改使它支持命令队列的功能,使它包一个装命令的容器,当里面有命令的时候取出来执行。
参考资料:
PatternCraft – Command Pattern(非常好!)
<<Head First Design Pattern>>
<<Design Patterns—Elements of Reusable Object-Oriented Software>>