您的位置:首页 > 其它

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

2012-11-06 10:40 176 查看
/**********************************************************************

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;
}

*****************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: