[行为模式] head first 设计模式之命令模式(Command)
1 意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式可以将"动作的请求者"从"动作的执行者"对象中解耦。
2 别名
动作(Action) 事物(Transaction)
以前做过一个项目,类似控制台的命令,把复杂的请求和相应利用Command模式进行封装;
//////////////////////////////////////////////////////////////////////////#include "Reciever.h"class Reciever;class Command{public: virtual ~Command(){}virtual void Excute() = 0;protected: Command(){}};class ConcreteCommand : public Command{public: ConcreteCommand(Reciever *rev){this->_rev = rev;} ~ConcreteCommand(){} void Excute(){this->_rev->Action();}private:Reciever *_rev;};//////////////////////////////////////////////////////////////////////////#include <iostream>using namespace std;class Reciever{public: Reciever(){} ~Reciever(){}void Action() { cout << "Reciever action..."<<endl; }};//////////////////////////////////////////////////////////////////////////#include "Command.h"class Command;class Invoker{public: Invoker(Command *cmd){this->_cmd = cmd;} ~Invoker(){} void Invoke(){this->_cmd->Excute();}private:Command *_cmd;};int main(int argc, char *argv[]){Reciever *rev = new Reciever();Command *cmd = new ConcreteCommand(rev);Invoker *inv = new Invoker(cmd);inv->Invoke();return 0;}
#include <iostream>#include <cassert>#include <string>using namespace std;//命令模式namespace Command{//////////////////////////////////////////////////////////////////////////const int REMOTE_SIZE = 7;//////////////////////////////////////////////////////////////////////////class Light{public: Light(){} Light(string str){ m_Name = str;} void on(){ cout << m_Name.c_str() << " Light is on" << endl;} void off(){ cout << m_Name.c_str() << " Light is off" << endl;}private: string m_Name;};//////////////////////////////////////////////////////////////////////////class Command{public: virtual ~Command(){} virtual void execute() = 0; virtual char* getName() = 0;};//////////////////////////////////////////////////////////////////////////class LightOnCommand : public Command{public: LightOnCommand(Light* light) :m_Light(NULL) { this->m_Light = light; } ~LightOnCommand() { //if (m_Light != NULL) //{ // delete m_Light; //} } virtual void execute() { assert(m_Light != NULL); m_Light->on(); } virtual char* getName() { return "LightOnCommand"; }private: Light* m_Light;};//////////////////////////////////////////////////////////////////////////class LightOffCommand : public Command{public: LightOffCommand(Light* light) :m_Light(NULL) { this->m_Light = light; } ~LightOffCommand() { if (m_Light != NULL) { delete m_Light; } } virtual void execute() { assert(m_Light != NULL); m_Light->off(); } virtual char* getName() { return "LightOffCommand"; }private: Light* m_Light;};//////////////////////////////////////////////////////////////////////////class Stereo{public: void on(){ cout << "Stereo::on" << endl;} void setCD(){ cout << "Stereo::setCD" << endl;} void setVolume(int vol) { cout << "Stereo::setVolume(" << vol << ")"<< endl; }};//////////////////////////////////////////////////////////////////////////class StereoOnWithCDCommand : public Command{public: StereoOnWithCDCommand(Stereo* stereo) :m_Stereo(NULL) { m_Stereo = stereo; } virtual ~StereoOnWithCDCommand() { //if (m_Stereo != NULL) //{ // delete m_Stereo; //} } virtual void execute() { assert(m_Stereo != NULL); m_Stereo->on(); m_Stereo->setCD(); m_Stereo->setVolume(11); } virtual char* getName() { return "LightOffCommand"; }private: Stereo* m_Stereo;};//////////////////////////////////////////////////////////////////////////class SimpleRemoteControl{public: SimpleRemoteControl() :m_Slot(NULL) {} ~SimpleRemoteControl() { //if (m_Slot != NULL) //{ // delete m_Slot; //} } void setCommand(Command* command) { //if (m_Slot != NULL) //{ // delete m_Slot; //} m_Slot = command; } void buttonWasPressed() { assert(m_Slot != NULL); m_Slot->execute(); }private: Command* m_Slot;};//////////////////////////////////////////////////////////////////////////class RemoteControlTest{public: void run() { //test for simple remote control SimpleRemoteControl* remote = new SimpleRemoteControl(); Light* light = new Light(); LightOnCommand* lightOn = new LightOnCommand(light); remote->setCommand(lightOn); remote->buttonWasPressed(); delete light; delete lightOn; Stereo* stereo = new Stereo(); StereoOnWithCDCommand* stereoOnWithCDCommand = new StereoOnWithCDCommand(stereo); remote->setCommand(stereoOnWithCDCommand); remote->buttonWasPressed(); delete stereo; delete stereoOnWithCDCommand; delete remote; }};}//namespace Command