命令模式(Command Pattern)行为模式.
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
命令模式可以用在队列请求和日志请求。
餐厅对象对应到命令模式包括:command(订单),execute()(orderUP()),Client(顾客),Invoker(女招待),Receiver(快餐厨师),setCommand()(takeOrder())
命令模式的类图如下:
Client创建一个ConcreteCommand,并设置接收者。
Receiver接收者知道如何进行必要的工作,实现这个请求。任何类都可以当接收者。
Invoker这个调用者持有一个命令对象,并在某个时间点调用命令对象的execute()方法,将请求付诸实行。
Command为所有的命令声明了一个接口,调用命令对象的execute()方法,就可以让接收者进行相关的动作。
遥控器的类图:
RemoteLoader相当于主调函数。RemoteControl相当于遥控器,用setCommand()装载命令,用onButtonWasPushed()来控制遥控器。LightOnCommand对象继承Command接口并持有一个接收者对象(如Light)。
流程如下:1.创建一个遥控器RemoteControl,即调用者对象Invoker。
2.创建接收者Light,即Receiver
3. 遥控器RemoteControl调用setCommand()装载命令。
4. RemoteControl控制命令
将请求封装在一个对象(command)中,并将请求的接受者放到具体的command中 (LightOnCommand)Receiver,从而实现调用操作的对象和操作的具体实现者之间的解耦。
HeadFirst 遥控器的例子实现C++
Receiver.h 头文件:
#ifndef _RECEIVER_H_
#define _RECEIVER_H_
//Reciever.h
//命令接收者
class Light
{
public:
Light();
~Light();
void on();
void off();
};
class Stereo
{
public:
Stereo();
~Stereo();
void on();
void setCD();
void setVolume(int volume);
void off();
};
#endif
Receiver.CPP
#include"Receiver.h"
#include<iostream>
using namespace std;
Light::Light()
{
}
Light::~Light()
{
}
void Light::on()
{
cout<<"light is on...."<<endl;
}
void Light::off()
{
cout<<"light is off..."<<endl;
}
Stereo::Stereo()
{
}
Stereo::~Stereo()
{
}
void Stereo::on()
{
cout<<"stereo is on ..."<<endl;
}
void Stereo::setCD()
{
cout<<"stereo is set for CD input"<<endl;
}
void Stereo::setVolume(int volume)
{
cout<<"stereo volume set to "<<volume<<endl;
}
void Stereo::off()
{
cout<<"stereo is off..."<<endl;
}
Command.h头文件
#ifndef _COMMAND_H_
#define _COMMAND_H_
class Light;
class Stereo;
//命令接口
class Command
{
public:
virtual ~Command();
virtual void Execute()=0;
protected:
Command();
private:
};
//空命令
class NoCommand:public Command
{
public:
NoCommand();
~NoCommand();
void Execute();
protected:
private:
};
//具体的命令
class LightOnCommand:public Command
{
public:
LightOnCommand(Light* pRec);
~LightOnCommand();
void Execute();
protected:
private:
Light* pRec; //命令的接收者
};
class LightOffCommand:public Command
{
public:
LightOffCommand(Light *pRec);
~LightOffCommand();
void Execute();
protected:
private:
Light * pRec;//命令的接收者
};
class StereoOnWithCDCommand:public Command
{
public:
StereoOnWithCDCommand(Stereo * pRec);
~StereoOnWithCDCommand();
void Execute();
protected:
private:
Stereo * pRec;
};
class StereoOffWithCDCommand:public Command
{
public:
StereoOffWithCDCommand(Stereo * pRec);
~StereoOffWithCDCommand();
void Execute();
protected:
private:
Stereo * pRec;
};
#endif
Command.CPP源文件
#include "Command.h"
#include"Receiver.h"
Command::Command()
{
}
Command::~Command()
{
}
NoCommand::NoCommand()
{
}
NoCommand::~NoCommand()
{
}
void NoCommand::Execute()
{
}
LightOnCommand::LightOnCommand(Light *pRec)
{
this->pRec=pRec;
}
LightOnCommand::~LightOnCommand()
{
}
void LightOnCommand::Execute()
{
pRec->on();
}
LightOffCommand::LightOffCommand(Light *pRec)
{
this->pRec=pRec;
}
LightOffCommand::~LightOffCommand()
{
}
void LightOffCommand::Execute()
{
pRec->off();
}
StereoOnWithCDCommand::StereoOnWithCDCommand(Stereo *pRec)
{
this->pRec=pRec;
}
StereoOnWithCDCommand::~StereoOnWithCDCommand()
{
}
void StereoOnWithCDCommand::Execute()
{
pRec->on();
pRec->setCD();
pRec->setVolume(11);
}
StereoOffWithCDCommand::StereoOffWithCDCommand(Stereo *pRec)
{
this->pRec=pRec;
}
StereoOffWithCDCommand::~StereoOffWithCDCommand()
{
}
void StereoOffWithCDCommand::Execute()
{
this->pRec->off();
}
Invoker.h头文件
#ifndef _INVOKER_H_
#define _INVOKER_H_
#include<list>
#include<vector>
using namespace std;
class Command;
//请求发送者
class RemoteControl
{
public:
RemoteControl();
~RemoteControl();
void setCommand(int slot,Command *pOnCmd,Command *pOffCmd);
void onButtonWasPushed(int slot);
void offButtonWasPushed(int slot);
protected:
private:
//list<Command *>* pOnCmd;
//list<Command *>* pOffCmd;
vector<Command *> pOnCmd;
vector<Command *> pOffCmd;
};
#endif
Invoker.CPP
#include "Invoker.h"
#include "Command.h"
RemoteControl::RemoteControl()
{
Command *pCmd=new NoCommand();
for(int i=0;i<2;i++)
{
pOnCmd.push_back(pCmd);
pOffCmd.push_back(pCmd);
//pOnCmd->push_front(pCmd);
//pOffCmd->push_front(pCmd);
}
}
RemoteControl::~RemoteControl()
{
}
void RemoteControl::setCommand(int slot, Command *pOnCmd, Command *pOffCmd)
{
this->pOnCmd.at(slot)=pOnCmd;
this->pOffCmd.at(slot)=pOffCmd;
}
void RemoteControl::onButtonWasPushed(int slot)
{
this->pOnCmd.at(slot)->Execute();
}
void RemoteControl::offButtonWasPushed(int slot)
{
this->pOffCmd.at(slot)->Execute();
}
主函数main.CPP
#include"Command.h"
#include"Receiver.h"
#include"Invoker.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
RemoteControl *remoteControl=new RemoteControl();//创建遥控器
//创建接收者
Light *roomLight=new Light();
Stereo *stereo=new Stereo();
//创建命令
LightOnCommand *roomLightOn=new LightOnCommand(roomLight);
LightOffCommand *roomLightOff=new LightOffCommand(roomLight);
StereoOnWithCDCommand *stereoOn=new StereoOnWithCDCommand(stereo);
StereoOffWithCDCommand *stereoOff=new StereoOffWithCDCommand(stereo);
//装载命令
remoteControl->setCommand(0,roomLightOn,roomLightOff);
remoteControl->setCommand(1,stereoOn,stereoOff);
//控制遥控器
remoteControl->onButtonWasPushed(0);
remoteControl->onButtonWasPushed(1);
remoteControl->offButtonWasPushed(0);
remoteControl->offButtonWasPushed(1);
return 0;
}