c++设计模式:命令模式(Command Pattern)

定义:

命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,命令模式也支持可撤销的操作。命令模式可将“动作的请求者”从“动作的执行者”对象中解耦。

场景:

我们要设计一个遥控器,可以通过按动上边的控制按钮控制卧室和厨房的灯,还能控制卧室中的音响的开关。遥控器及时我们的“动作的请求者”,而灯和音响就是我们的“动作的执行者”。当我们按动遥控器上的某个开关后,遥控器就可以把相关的指令发送到我们的指定的家电上。这之中遥控器和家电之间是解耦的,我们完全可以通过设置,添加、修改或删除其它的家电控制功能,而不需要修改遥控器的代码。

类图:

 

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 设计模式》


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值