设计模式之实现---命令模式

/**********************************************************************

CCommand.h

**********************************************************************/

#pragma once
#include "Objects.h"
#include <iostream>
using namespace std;


//命令对象类的基类
class CCommand
{
public:
 virtual void execute() = 0;
};

//空命令对象,什么都不做。只实现了一个接口
class CEmptyCommand : public CCommand
{
public:
 void execute(){};
};

/////////////////////////
//Light on command
class CLightOnCommand : public CCommand
{
 CLight* m_Light;
public:
 CLightOnCommand(CLight* inLight) : m_Light(inLight){}
 void execute(){
  if(!m_Light)
   return;
  m_Light->turnOn();
 }
};

//////////////////////
//Light off command
class CLightOffCommand : public CCommand
{
 CLight* m_Light;
public:
 CLightOffCommand(CLight* inLight) : m_Light(inLight){}
 void execute(){
  if(!m_Light)
   return;
  m_Light->turnOff();
 }
};

//开计算机的命令
class CComputerStartCommand : public CCommand
{
 CComputer* m_Computer;
public:
 CComputerStartCommand(CComputer* inPC) : m_Computer(inPC){}
 void execute(){
  m_Computer->Start();
 }
};


//关闭计算机的命令
class CComputerShutDownCommand : public CCommand
{
 CComputer* m_Computer;
public:
 CComputerShutDownCommand(CComputer* inPC) : m_Computer(inPC){}
 void execute(){
  m_Computer->Start();
 }
};

/**************************************************************

CController.h

**************************************************************/

#pragma  once;
#include <iostream>
#include <vector>
#include "CCommand.h"
using namespace std;


//设计一个摇控器来测试我们的命令模式
class CController
{
private:
 vector<CCommand*> m_turnOnCommand;
 vector<CCommand*> m_turnOffCommand;

public:
 CController(CCommand* defaultCommandForAll){
  //假设默认有6上按钮
  for(int i = 0; i < 6; i++){
   //将所有按钮设置为空按钮
   m_turnOffCommand.push_back(defaultCommandForAll);
   m_turnOnCommand.push_back(defaultCommandForAll);
  }
 }

 void setCommand(int commandIdx, CCommand* command, bool turnOn = true){
  //这里涉及到在哪里销毁之前的command对象
  //一般来说主张在哪里new,就要在哪里删。但这里怕删了后又要被用到就比较麻烦了。
  //所以我的做法是在construct这个摇控器的时候,传一个空按钮进来。
  //这样可以保证按钮的动作始终是可以被完成的。而不用担心空对象的问题。
  if( commandIdx < 0 || commandIdx >= 6 || !command)
   return;
  if(turnOn) {
   m_turnOnCommand[commandIdx] = command;
  }
  else{
   m_turnOffCommand[commandIdx] = command;
  }
 }

 void OnButtonPressed(int idx)
 {
  m_turnOnCommand[idx]->execute();
 }

 void OffButtonPressed(int idx)
 {
  m_turnOffCommand[idx]->execute();
 }

};

/********************************************************************

Objects.h

*******************************************************************/

#pragma once
#include <iostream>
using namespace std;

class CLight
{
public:
 void turnOn(){
  cout<<"The Light is turned on!"<<endl;
 }

 void turnOff(){
  cout<<"The light is turned off!"<<endl;
 }
};

class CComputer
{
public:
 void Start(){
  cout<<"Computer is starting"<<endl;
 }

 void Shutdown(){
  cout<<"The computer is shutting down"<<endl;
 }
};

class CAirCondition
{
public:
 void turnOn(){
  cout<<"The Air Conditioning is turned on"<<endl;
 }

 void turnOff(){
  cout<<"The Air Conditioning is turned off"<<endl;
 }

 void RaiseUpTemperature(){
  cout<<"Temperature Up..."<<endl;
 }

 void RaiseDownTemperature(){
  cout<<"Temperature Down..."<<endl;
 }
};

/**************************************************************

testCommandPattern.cpp

*********************

/*
设计模式: 命令模式。

    请“请求”封闭成对象,以便使用不同的请求、队列勤于得日志来参数化其他对象。命令模式也支持可撤销的操作。

    命令对象将动作和接收者包进对象中。这个对象只出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。

    在实际操作时,很常见使用“聪明”命令对象,也就是直接实现了请求,而不是将工作委托给接收者。

    我的理解,命令模式是两个has-a的关系。
    1 .第一个has-a是命令控制类(由client控制)中有一个(当然也可以有多个)有着统一接口的命令类(去做一些事,这些事被封装在execute里)的实例,
可以通过某些方法来调用这些命令类实例的统一方法execute。
    2, 第二个has-a是命令类里有一个实物类(真正处理事务的类)的实例,在重载的execute(这个execute函数可以理解为触发真实事件的invoker)中来触发实物类的方法组合。
 通过这种设计就可以使调用者和接收者之间进行解耦。

    命令模式总得来是是用一个命令对象在各个类间的传递。

by 何戬, hejian@cad.zju.edu.cn
*/


#include <iostream>
#include "CController.h"
using namespace std;

int main()
{
 CEmptyCommand* emptyCommand = new CEmptyCommand();
 CController* cont = new CController(emptyCommand);
 CLight* light1 = new CLight();
 CCommand* lightOnCommand = new CLightOnCommand(light1);
 CCommand* lightOffCommand = new CLightOffCommand(light1);
 
 cont->setCommand(0, lightOnCommand, true);
 cont->setCommand(0, lightOffCommand, false);
 cont->OnButtonPressed(0);
 cont->OffButtonPressed(0);

 CComputer* pc = new CComputer();
 CComputerStartCommand* pcstart = new CComputerStartCommand(pc);
 CComputerShutDownCommand* pcsd = new CComputerShutDownCommand(pc);
 cont->setCommand(1, pcstart, true);
 cont->setCommand(1, pcsd, false);
 cont->OnButtonPressed(1);
 cont->OffButtonPressed(1);

 /*
 写得很开心,不过今天写了一天了,太累了。
 如果你是第一个看这个程序的人,请我帮air condition的on, off, raise temperature和lower tempertuare的命令加上。哈哈。
 */

 delete pcsd;
 delete pcstart;
 delete pc;

 delete lightOffCommand;
 delete lightOnCommand;
 delete light1;
 delete cont;
 delete emptyCommand;
 return 0;
}

*****************************************/

 

posted on 2012-11-06 10:40  bitbit  阅读(273)  评论(0编辑  收藏  举报