7. 命令模式

来源:互联网 发布:d3.js v4画力导向图 编辑:程序博客网 时间:2024/05/18 01:34

        这个模式的深入的了解下来内容还是很多的。文中使用遥控器的例子,对此模式的各种用法进行了详细介绍。总结出以下几点内容: 

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()进行处理。

3.2 数据库操作的redo

      由于系统可能宕机,需要在宕机后恢复到之前的状态。所以在执行每个命令时会将命令存储在磁盘(记录日志)中,在做恢复时重新加载这些对象,并按顺序执行。








原创粉丝点击