版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/llz62378/article/details/78168933
这个模式的深入的了解下来内容还是很多的。文中使用遥控器的例子,对此模式的各种用法进行了详细介绍。总结出以下几点内容:
1. 各种命令
1.1 开关一个设备execute
一个遥控器中有多个按钮,可以控制多个设备的开关。
class RemoteControl
{
public:
RemoteControl();
void SetCommand(int idx, Command *onCmd, Command *offCmd)
void OnButtonWasPushed(int idx)
void OffButtonWasPushed(int idx)
void Undo(int idx);
private:
Command *onCmd;
Command *offCmd;
Command *undoCmd;
};
RemoteControl::RemoteControl()
{
onCmd = new Command[7];
offCmd = new Command[7];
Command *noCmd = new NoCmd(); //空对象, 好处在执行时不需要判断cmd是否为null.
for(int i =0; i<7; ++i)
{
onCmd[i] = noCmd;
offCmd[i] = noCmd;
}
undoCmd = noCmd;
}
void RemoteControl::SetCommand(int idx, Command *onCmd, Command *offCmd)
{
onCmd[idx] = onCmd;
offCmd[idx] = offCmd;
}
void RemoteControl::OnButtonWasPushed(int idx)
{
onCmd[idx].execute();
}
void RemoteControl::OffButtonWasPushed(int idx)
{
offCmd[idx].execute();
}
LightOnCmd::LightOnCmd(Light *light)
{
this->light = light;
}
void LightOnCmd::Execute()
{
light->On();
}
LightOffCmd::LightOffCmd(Light *light)
{
this->light = light;
}
void LightOffCmd::Execute()
{
light->Off();
}
client:
RemoteControl *remoteControl = new RemoteControl();
Light *light = new Light();
LightOnCmd *lightOnCmd = new LightOnCmd(light);
LightOffCmd *lightOffCmd = new LightOffCmd(light);
remoteControl->SetCommand(0, lightOnCmd, lightOffCmd);
remoteControl->OnButtonWasPushed(0); // 开灯
remoteControl->OffButtonWasPushed(0); // 关灯
1.2 撤销命令undo
1.2.1 撤销一个命令
void RemoteControl::OnButtonWasPushed(int idx)
{
onCmd[idx].execute();
undoCmd = onCmd[idx];
}
void RemoteControl::OffButtonWasPushed(int idx)
{
offCmd[idx].execute();
undoCmd = offCmd[idx];
}
void RemoteControl::UndoButtonWasPushed()
{
undoCmd->Undo();
}
(1)两个状态的情况,eg. light
void LightOnCmd::Execute()
{
light->On();
}
void LightOnCmd::Undo()
{
light->Off();
}
void LightOffCmd::Execute()
{
light->Off();
}
void LightOffCmd::Undo()
{
light->On();
}
(2)三个状态的情况,eg. fan
int Fan::GetState()
{
return undoState;
}
void FanHighCmd::Execute()
{
undoState = fan->GetState();
fan->High();
}
void FanMidCmd::Execute()
{
undoState = fan->GetState();
fan->Mid();
}
void FanLowCmd::Execute()
{
undoState = fan->GetState();
fan->Low();
}
void FanLowCmd::Undo()
{
if(undoState == HIGH)
fan->High();
else if(undoState == MID)
fan->Mid();
else if(undoState == LOW)
fan->Low();
else if(undoState == OFF)
fan->Off();
else
fan->On();
}
client:
remoteControl->UndoButtonWasPushed()
1.2.2 撤销多个命令
在RemoteControl中添加stack<Command *> undoCmd;记录命令。先从stack取栈顶的cmd对象,再执行它的undo命令。
2. party模式
void MacroCommand::MacroCommand(Command *cmds[])
{
this->cmds = cmds;
}
void MacroCommand::Execute()
{
for(auto i:cmds)
i->Execute();
}
client:
// 1. 创建设备
Light *light = new Light();
TV *tv = new TV();
Stereo *stereo = new Stereo();
// 2. 创建对设备的操作
LightOnCmd *lightOnCmd = new LightOnCmd(light);
TVOnCmd *tvOnCmd = new TVOnCmd(tv);
StereoOnCmd *stereoOnCmd = new StereoOnCmd(stereo);
LightOffCmd *lightOffCmd = new LightOffCmd(light);
TVOffCmd *tvOffCmd = new TVOffCmd(tv);
StereoOffCmd *stereoOffCmd = new StereoOffCmd(stereo);
// 3. 将一起执行的命令放在命令集中
Command *partyOn[3] = {lightOnCmd,tvOnCmd,stereoOnCmd};
Command *partyOff[3] = {lightOffCmd,tvOffCmd,stereoOffCmd};
// 4. 创建多命令一起操作的对象
MacroCommand partyOnMacro = new MacroCommand(partyOn);
MacroCommand partyOffMacro = new MacroCommand(partyOff);
// 5. 注册命令:将多命令放入遥控器中
remoteCommand.setCommand(0, partyOnMacro, partyOffMacro);
//6.执行命令
remoteCommand.OnButtonWasPushed(0);
remoteCommand.OffButtonWasPushed(0);
3. 两个应用
3.1 工作队列
将一个个命令放入到工作队列中,之后由线程从队列中取命令,执行相应命令的execute()进行处理。