命令模式
来源:互联网 发布:明解c语言pdf 编辑:程序博客网 时间:2024/06/05 20:48
设计理念
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。
考虑现实我们在开发的过程中经常会遇到这样的场景吧:我们需要执行一个时间特别长的任务,如果我们将这个长任务与其他的任务一起采用同步执行的方式,就会阻塞其他任务的运转,这个时候,我们可能通过异步命令的方式来操作,就能大大提升CPU的使用率。
在游戏编程中,命令模式也是常客。如果将按键与对应的执行命令硬编码,虽然可以正常的工作但也存在很大的局限,如若使用命令模式将请求者和接受者解耦,通过在命令和角色间增加了一层重定向, 我们获得了一个灵巧的功能:我们可以让玩家控制游戏中的任何角色,只需向命令传入不同的角色。
UML框图
- Command: 抽象命令类,定义命令的接口,申明执行的方法;
- ConcreteCommand:具体命令类,实现要执行的方法,它通常是“虚”的表现;通常会有接受者,并调用接受者的功能来完成命令要执行的操作;
- Invoker: 调用者,要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象;
- Receiver: 接收者,真正执行命令的对象;
- Client:客户类,最终的客户端调用类。
实现代码
//main.cpp#include <iostream>#include "ConcreteCommand.h"#include "Invoker.h"#include "Receiver.h"using namespace std;int main(int argc, char *argv[]){ Receiver * pReceiver = new Receiver(); ConcreteCommand * pCommand = new ConcreteCommand(pReceiver); Invoker * pInvoker = new Invoker(pCommand); pInvoker->call(); delete pReceiver; delete pCommand; delete pInvoker; return 0;}
///////////////////////////////////////////////////////////// Receiver.h// Implementation of the Class Receiver///////////////////////////////////////////////////////////class Receiver{public: Receiver(); virtual ~Receiver(); void action();};
///////////////////////////////////////////////////////////// Receiver.cpp// Implementation of the Class Receiver///////////////////////////////////////////////////////////#include "Receiver.h"#include <iostream>using namespace std;Receiver::Receiver(){}Receiver::~Receiver(){}void Receiver::action(){ cout << "receiver action." << endl;}
///////////////////////////////////////////////////////////// ConcreteCommand.h// Implementation of the Class ConcreteCommand///////////////////////////////////////////////////////////#include "Command.h"#include "Receiver.h"class ConcreteCommand : public Command{public: ConcreteCommand(Receiver * pReceiver); virtual ~ConcreteCommand(); virtual void execute();private: Receiver *m_pReceiver;};
///////////////////////////////////////////////////////////// ConcreteCommand.cpp// Implementation of the Class ConcreteCommand///////////////////////////////////////////////////////////#include "ConcreteCommand.h"#include <iostream>using namespace std;ConcreteCommand::ConcreteCommand(Receiver *pReceiver){ m_pReceiver = pReceiver;}ConcreteCommand::~ConcreteCommand(){}void ConcreteCommand::execute(){ cout << "ConcreteCommand::execute" << endl; m_pReceiver->action();}
///////////////////////////////////////////////////////////// Invoker.h// Implementation of the Class Invoker///////////////////////////////////////////////////////////#include "Command.h"class Invoker{public: Invoker(Command * pCommand); virtual ~Invoker(); void call();private: Command *m_pCommand;};
///////////////////////////////////////////////////////////// Invoker.cpp// Implementation of the Class Invoker///////////////////////////////////////////////////////////#include "Invoker.h"#include <iostream>using namespace std;Invoker::Invoker(Command * pCommand){ m_pCommand = pCommand;}Invoker::~Invoker(){}void Invoker::call(){ cout << "invoker calling" << endl; m_pCommand->execute();}
总结
命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
命令模式的主要优点在于降低系统的耦合度,增加新的命令很方便,而且可以比较容易地设计一个命令队列和宏命令,并方便地实现对请求的撤销和恢复;其主要缺点在于可能会导致某些系统有过多的具体命令类。
参考链接
http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html
http://gpp.tkchu.me/command.html