命令模式
- 将一个请求封装成一个对象,请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
- UML图:
例子
说明:在路边大排档,客人有需要考串,烤鸡腿等命令。客人将命令传给服务员,服务员再将命令交给厨师。
厨师类:能够执行:烤串、烤鸡腿命令
class Cooker
{
public:
void MakeShashlik()
{
cout << "进行烤串" << endl;
}
void MakeChiken()
{
cout << "进行烤鸡腿" << endl;
}
};
命令类:
class Command
{
public:
Command(Cooker& cooker)
{
m_cooker = cooker;
}
virtual void excute() = 0;
protected:
Cooker m_cooker;
};
烤串命令
class CommandOfShashlik :public Command
{
public:
CommandOfShashlik(Cooker& cooker) :Command(cooker)
{
}
virtual void excute()
{
m_cooker.MakeShashlik();
}
};
烤鸡腿命令
class CommandOfChiken :public Command
{
public:
CommandOfChiken(Cooker& cooker) :Command(cooker)
{
}
virtual void excute()
{
m_cooker.MakeChiken();
}
};
服务员类:将客人的命令收集到list,然后统一交给厨师执行
class Waitress
{
public:
void SetCommand(Command* command)
{
list_comd.push_back(command);
}
void PlaceOrder()
{
list<Command*>::iterator it = list_comd.begin();
for (; it != list_comd.end(); it++)
{
(*it)->excute();
}
}
private:
list <Command*> list_comd;
};
调用:
int main()
{
Waitress waitress;
Cooker cooker;
CommandOfChiken* Chiken = new CommandOfChiken(cooker);
CommandOfShashlik* Shashlik= new CommandOfShashlik(cooker);
waitress.SetCommand(Chiken);
waitress.SetCommand(Shashlik);
waitress.PlaceOrder();
return 0;
}
结果:最后厨师执行客人的两个命令
- 优点:
(1) 降低系统的耦合度。由于请求者与接收者之间不存在直接引用,因此请求者与接收者之间实现完全解耦,相同的请求者可以对应不同的接收者,同样,相同的接收者也可以供不同的请求者使用,两者之间具有良好的独立性。
(2) 新的命令可以很容易地加入到系统中
(3) 可以比较容易地设计一个命令队列
- 缺点:
需使用命令模式可能会导致某些系统有过多的具体命令类。
- 使用场景:
(1) 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
(2) 系统需要在不同的时间指定请求、将请求排队和执行请求。
(3) 系统需要将一组操作组合在一起形成宏命令。