1 意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式可以将"动作的请求者"从"动作的执行者"对象中解耦。
2 别名
动作(Action) 事物(Transaction)
[img]http://t25-3.yunpan.360.cn/p/800-600.9488f768b87b9a43524b445c376cdbacf496ccbf.b223cb.jpg?t=a344bfb34b846467f2df389c48ad5ce8&d=20130821[/img]
以前做过一个项目,类似控制台的命令,把复杂的请求和相应利用Command模式进行封装;
在headfirst中采用的是遥控器的例子,具体如下:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式可以将"动作的请求者"从"动作的执行者"对象中解耦。
2 别名
动作(Action) 事物(Transaction)
[img]http://t25-3.yunpan.360.cn/p/800-600.9488f768b87b9a43524b445c376cdbacf496ccbf.b223cb.jpg?t=a344bfb34b846467f2df389c48ad5ce8&d=20130821[/img]
以前做过一个项目,类似控制台的命令,把复杂的请求和相应利用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;
}
在headfirst中采用的是遥控器的例子,具体如下:
#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