第七章 命令模式

这篇博客介绍了如何运用命令模式设计一个遥控器的控制逻辑。遥控器包含多个按键,如开/关灯、音量加减和撤销操作。每个按键对应一个具体命令,例如LightOn_Off_cmd用于控制灯的开关。当按下按键时,遥控器执行相应的命令,如果按下撤销键,将执行上一个命令的撤销操作。博客中展示了如何通过C++实现这一设计模式,包括命令接口、具体命令类、接收者类和控制器类的定义及交互过程。
摘要由CSDN通过智能技术生成

1. 设计模型

在这里插入图片描述

说明:
Command::execute, 一个执行命令的抽象接口
Concrete Command, 具体的命令,比如开灯/关灯命令
Receiver, 具体的被操控对象,比如灯自身(开灯、关灯、闪烁、颜色控制都在Receiver这里)
Invoker,封装命令的类。下面我们看一个控制器的例子

2. 一个按键控制器

2.1 设计方案

在这里插入图片描述

2.2 设计说明

一、考虑遥控器常见的按键:
①关灯/开灯 作为一个按键实现
②音量+ 作为一个单独按键实现
③音量- 作为一个单独按键实现
④ Undo 按键作为撤销操作

二、RemoteControl 针对遥控器上的每一个按键保留一个slot。

2.3 设计代码

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

/*keypad design*/
enum KEYSLOTS
{
    LightOn_Off,VolumeUp,VolumeDown,Undo,KeyMax
};

/*Command design*/
class Command
{
public:
virtual void execute(void){}
virtual void Undo(void){}
};

class RemoteControl
{
public:
    RemoteControl(void)
    {
        Commands.resize(KeyMax);
    }
    void setCommand(enum KEYSLOTS slotiId, Command * command)
    {
        Commands[slotiId] = command;
    }
    void KeyPressed(enum KEYSLOTS slotId)
    {
        if(slotId == Undo)
        {
             auto temp = Commands[LastPressed];
             temp->Undo(); 
        }
        else
        {
            LastPressed = slotId;
            Commands[slotId]->execute();   
        }

    }
private:
static  enum KEYSLOTS LastPressed;
std::vector<Command*> Commands;
};
enum KEYSLOTS RemoteControl::LastPressed;


/*Light design*/
class Led
{
public:
Led(void)
{
    currState = OFF;
}
enum LedState {ON, OFF};

    void lightOn(void)
    {
        cout << "light on" << endl;
    }
    void lightOff(void)
    {
        cout << "light off" << endl;
    }  
enum LedState currState;
};

/*Volume design*/
class Volume
{
public:
    void VolumeUp(void)
    {
        cout << "volume up" << endl;
    }
    void VolumeDown(void)
    {
        cout << "volume down" << endl;
    }    
};

/*Concrete Command design*/
class LightOn_Off_cmd: public Command
{
public:
    LightOn_Off_cmd(Led * led= NULL):m_led(led){}
    void execute(void)
    {
        if(m_led->currState == Led::ON)
       {
           m_led->lightOff();
           m_led->currState = Led::OFF;
       }
       else
       {
           m_led->lightOn();
           m_led->currState = Led::ON;
       }
    }
    void Undo(void)
    {
        if(m_led->currState == Led::ON)
        {
           m_led->lightOff();
           m_led->currState = Led::OFF;
        }
        else
        {
           m_led->lightOn();
           m_led->currState = Led::ON;            
        }
    }
Led *m_led;
};

class VolumeDown_cmd:public Command
{
    /*to do*/
};
class VolumeUp_cmd:public Command
{
    /*to do*/
};
int main ()
{
    Led * led = new Led;
    LightOn_Off_cmd *ledcmd = new LightOn_Off_cmd(new Led);

    RemoteControl remoteCtrl;
    remoteCtrl.setCommand(LightOn_Off, ledcmd);
    remoteCtrl.KeyPressed(LightOn_Off);
    remoteCtrl.KeyPressed(LightOn_Off);
    remoteCtrl.KeyPressed(LightOn_Off);
    
    remoteCtrl.KeyPressed(Undo);
    remoteCtrl.KeyPressed(Undo);    
    
    cout << "main" << endl;

    delete led;
    delete ledcmd;
    
  return 0;
}

输出:
light on
light off
light on
light off
light on
main

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值