文章目录
前言
日常生活中,我们去饭馆吃饭一般都是找服务员点菜,而不是直接给厨师下菜单?其实,这种点菜的方式就是命令模式:我们点的菜单就是一个个请求,点菜员记录的菜单就是将请求生成的对象,点菜员不需要关心怎么做菜、谁来做,他只要把菜单传到后厨即可,由后厨统一调度。
简而言之,命令模式就是把请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
一、命令模式(Command模式)
Command 模式中,将请求的接收者(Reciever)放到 Command 的具体子类ConcreteCommand 中,当请求到来时(Invoker 发出 Invoke 消息激活 Command 对象),ConcreteCommand 将处理请求交给 Receiver 对象进行处理。UML图如下:
二、具体源码
1.Reciever.h
代码如下(示例):
#ifndef _RECIEVER_H_
#define _RECIEVER_H_
#include <iostream>
class Reciever
{
public:
Reciever();
~Reciever();
void Action();
protected:
private:
};
#endif //_RECIEVER_H_
2.Reciever.cpp
代码如下(示例):
#include "Reciever.h"
Reciever::Reciever()
{
}
Reciever::~Reciever()
{
}
void Reciever::Action()
{
std::cout << "Reciever action......." << std::endl;
}
3.Command.h
代码如下(示例):
#pragma once
#ifndef _COMMAND_H_
#define _COMMAND_H_
#include "Reciever.h"
class Command
{
public:
virtual ~Command();
virtual void Excute() = 0;
protected:
Command();
private:
};
class ConcreteCommand :public Command
{
public:
ConcreteCommand(Reciever* rev);
~ConcreteCommand();
void Excute();
protected:
private:
Reciever* _rev;
};
#endif //_COMMAND_H_
4.Command.cpp
代码如下(示例):
#include "Command.h"
Command::Command()
{
}
Command::~Command()
{
}
void Command::Excute()
{
}
ConcreteCommand::ConcreteCommand(Reciever* rev)
{
this->_rev = rev;
}
ConcreteCommand::~ConcreteCommand()
{
delete this->_rev;
}
void ConcreteCommand::Excute()
{
_rev->Action();
std::cout << "ConcreteCommand..." << std::endl;
}
5.Invoker.h
代码如下(示例):
#pragma once
#ifndef _INVOKER_H_
#define _INVOKER_H_
#include "Command.h"
class Invoker
{
public:
Invoker(Command* cmd);
~Invoker();
void Invoke();
protected:
private:
Command* _cmd;
};
#endif //_INVOKER_H_
6.Invoker.cpp
代码如下(示例):
#include "Invoker.h"
Invoker::Invoker(Command* cmd)
{
_cmd = cmd;
}
Invoker::~Invoker()
{
delete _cmd;
}
void Invoker::Invoke()
{
_cmd->Excute();
}
7.main.cpp
代码如下(示例):
#include "Command.h"
#include "Invoker.h"
#include "Reciever.h"
int main(int argc, char* argv[])
{
Reciever* rev = new Reciever();
Command* cmd = new ConcreteCommand(rev);
Invoker* inv = new Invoker(cmd);
inv->Invoke();
return 0;
}
三、运行结果
Command模式运行结果如下:
总结
Command 模式的思想非常简单,而且也十分常见。实际上,Command 模式关键就是提供一个抽象的 Command 类,并将执行操作封装到 Command类接口中,Command 类中一般就是只是一些接口的集合,并不包含任何的数据属性(当然在示例代码中,我们的 Command 类有一个处理操作的 Receiver 类的引用,但是其作用也仅仅就是为了实现这个 Command 的 Excute 接口)。Command 模式的优点如下:
1)将调用操作的对象和知道如何实现该操作的对象解耦。如上,Invoker 对象根本就不知道具体的是那个对象在处理 Excute操作;
2)增加新的处理操作对象很容易,只需通过创建新的继承自Command 的子类来实现即可。
本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。