c++設計模式:命令模式(Command Pattern)

來源:互聯網
上載者:User

定義:

命令模式將“請求”封裝成對象,以便使用不同的請求、隊列或者日誌來參數化其他對象,命令模式也支援可撤銷的操作。命令模式可將“動作的要求者”從“動作的執行者”對象中解耦。

情境:

我們要設計一個遙控器,可以通過按動上邊的控制按鈕控制臥室和廚房的燈,還能控制臥室中的音響的開關。遙控器及時我們的“動作的要求者”,而燈和音響就是我們的“動作的執行者”。當我們按動遙控器上的某個開關後,遙控器就可以把相關的指令發送到我們的指定的家電上。這之中遙控器和家電之間是解耦的,我們完全可以通過設定,添加、修改或刪除其它的家電控制功能,而不需要修改遙控器的代碼。

類圖:

 

c++代碼如下:

#include <iostream>
#include <vector>
using namespace std;

class Command
{
public:
virtual void execute() = 0;
};

class NoCommand : public Command
{
public:
void execute() {};
};

class Light
{
public:
Light(string location);
void on();
void off();
private:
string m_sLocation;
};

class LightOffCommand : public Command
{
public:
LightOffCommand(string location):m_Light(location) {}
void execute();
private:
Light m_Light;
};

class LightOnCommand : public Command
{
public:
LightOnCommand(string location):m_Light(location) {}
void execute();
private:
Light m_Light;
};

class Stereo
{
public:
Stereo(string location);
void on();
void off();
void setCD();
void setDVD();
void setRadio();
void setVolume(int volume);
private:
string m_sLocation;
};

class StereoOnWithCDCommand : public Command
{
public:
StereoOnWithCDCommand(string location):m_Stereo(location) {}

void execute();
private:
Stereo m_Stereo;
};

class StereoOffCommand : public Command
{
public:
StereoOffCommand(string location):m_Stereo(location) {}

void execute();
private:
Stereo m_Stereo;
};

class RemoteControl
{
public:
RemoteControl();
~RemoteControl();
void setCommand(int slot, Command* pOnCommand, Command* pOffCommand);
void onButtonWasPushed(int slot);
void offButtonWasPushed(int slot);
private:
vector<Command*> m_OnCommands;
vector<Command*> m_OffCommands;
};

Light::Light(string location)
{
m_sLocation = location;
}

void Light::on()
{
printf("%s light is on\n",m_sLocation.c_str());
}

void Light::off()
{
printf("%s light is off\n",m_sLocation.c_str());
}

void LightOffCommand::execute()
{
m_Light.off();
}

void LightOnCommand::execute()
{
m_Light.on();
}

Stereo::Stereo(string location)
{
m_sLocation = location;
}

void Stereo::on()
{
printf("%s stereo is on\n",m_sLocation.c_str());
}

void Stereo::off()
{
printf("%s stereo is off\n",m_sLocation.c_str());
}

void Stereo::setCD()
{
printf("%s stereo is set for CD input\n",m_sLocation.c_str());
}

void Stereo::setDVD()
{
printf("%s stereo is set for DVD input\n",m_sLocation.c_str());
}

void Stereo::setRadio()
{
printf("%s stereo is set for Radio\n",m_sLocation.c_str());
}

void Stereo::setVolume(int volume)
{
printf("%s Stereo volume set to %d\n",m_sLocation.c_str(),volume);
}

void StereoOnWithCDCommand::execute()
{
m_Stereo.on();
m_Stereo.setCD();
m_Stereo.setVolume(11);
}

void StereoOffCommand::execute()
{
m_Stereo.off();
}

RemoteControl::RemoteControl()
{
for (int i = 0; i < 7; i++)
{
Command* noCommandOn = new NoCommand();
m_OnCommands.push_back(noCommandOn);
Command* noCommandOff = new NoCommand();
m_OffCommands.push_back(noCommandOff);
}
}

RemoteControl::~RemoteControl()
{
for (int i = 0; i < 7; i++)
{
delete m_OnCommands.at(i);
delete m_OffCommands.at(i);
}
m_OnCommands.clear();
m_OffCommands.clear();
}

void RemoteControl::setCommand(int slot, Command* pOnCommand, Command* pOffCommand)
{
delete m_OnCommands.at(slot);
m_OnCommands.at(slot) = pOnCommand;
delete m_OffCommands.at(slot);
m_OffCommands.at(slot) = pOffCommand;
}

void RemoteControl::onButtonWasPushed(int slot)
{
m_OnCommands.at(slot)->execute();
}

void RemoteControl::offButtonWasPushed(int slot)
{
m_OffCommands.at(slot)->execute();
}

int main()
{
RemoteControl remoteControl;
LightOffCommand* pLivingRoomLightOff = new LightOffCommand("Living Room");
LightOffCommand* pKitchenLightOff = new LightOffCommand("Kitchen");
LightOnCommand* pLivingRoomLightOn = new LightOnCommand("Living Room");
LightOnCommand* pKitchenLightOn = new LightOnCommand("Kitchen");
StereoOnWithCDCommand* pStereoOnWithCD = new StereoOnWithCDCommand("Living Room");
StereoOffCommand* pStereoOff = new StereoOffCommand("Living Room");

remoteControl.setCommand(0,pLivingRoomLightOn,pLivingRoomLightOff);
remoteControl.setCommand(1,pKitchenLightOn,pKitchenLightOff);
remoteControl.setCommand(2,pStereoOnWithCD,pStereoOff);

remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(1);
remoteControl.offButtonWasPushed(1);
remoteControl.onButtonWasPushed(2);
remoteControl.offButtonWasPushed(2);
return 0;
}

 

運行結果如下:

Living Room light is on

Living Room light is off

Kitchen light is on

Kitchen light is off

Living Room stereo is on

Living Room stereo is set for CD input

Living Room Stereo volume set to 11

Living Room stereo is off

 

參考圖書:《Head First 設計模式》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.