【行为型】Command模式

时间:2023-03-08 21:12:50
【行为型】Command模式

命令模式是指将用户的请求封装成(命令)对象,从而可将用户不同的请求进行参数化、对这些请求排序或记录请求日志、以及支持回滚恢复操作。记得以前刚开始使用Photoshop时,就发现它的操作历史记录面板特别好用,现在想想,其实也可以通过命令模式来设计。命令模式主要是将请求抽象成对象,以此作为中间的一个中转站,转达请求命令,从而将请求方与响应方解耦。在逻辑层面上,用户只需要发布自己的命令即可,至于由什么样的响应者来处理,则需要看具体下达的是什么样的命令。模式类结构图参考如下:

【行为型】Command模式

模式编码结构参考如下:

 namespace command
{
class Receiver
{
public:
void doAction() {/*some code here........*/} }; class ICommand
{
public:
virtual void action() = ;
// some code here........ }; class ConcreteCommand : public ICommand
{
public:
virtual void action() {
// some code here........
_receiver->doAction();
} private:
Receiver* _receiver; };//class ConcreteCommand class Invoker
{
public:
void call() {
// some code here........
// this is a test case below.
auto pCommand = new (std::nothrow) ConcreteCommand();
pCommand->action();
} }; }//namespace command

Command模式编码结构参考

既然命令对象的职责相当于是一个中转站转达请求,则命令模式重点在于命令对象的设计。试想下,如果一个请求需要被多个响应者响应,则只需要简简单单设计一个“复合命令”对象即可。参考如下:

 class MacroCommand
{
public:
// some code here........
virtual void execute() override {
// call execute action of all children command object
// some code here........
} private:
typedef std::list<ICommand*> TCmdList; TCmdList m_listCmds; };//class MacroCommand

复合命令编码参考

对于命令对象的设计,最复杂的情况是直接将响应者的逻辑直接在命令对象中封装起来,此时就相当于没有使用命令模式的情形,这是一种完全退化的情况。最简单的情况是将请求转抛给具体的响应者,此时命令对象就仅仅只是一个桥梁,起到的作用是将请求方与响应方解耦合。因此,关于命令对象的封装会有个度的评估,此需要看具体设计、项目实际需要、以及当时的上下文环境而斟酌。