C++设计模式10--命令模式(二)(Command)--降低请求发送者与接收者耦合


  工作了一天感觉好累,洗了个澡,打开电视看看有没有喜欢的节目,拿起遥控器,看着上面的按钮,忽然感觉好奇妙,我们按一开机键,电视就开了,然后...哈哈,真好玩,我按我按。细想之下这不就是一个命令模式么。

电视机是请求的接收者Receiver

遥控器是请求的发送者ConcreteCommand

遥控器上有一些按钮,不同的按钮对应电视机的不同操作。

抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现了抽象命令接口,这三个具体命令类分别代表三种操作:打开电视机、关闭电视机和切换频道。

显然,电视机遥控器就是一个典型的命令模式应用实例。

#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
using namespace std;
/*
电视机是请求的接收者,
    也只有它的内部有一堆指令集合可以执行各种命令,它才是命令的真正执行者
    因此它有Open打开电视, Close关闭电视,Change更换频道的接口
遥控器是请求的发送者,
    它内含命令的对象,
    负责将这个命令发送出去,因此需要有设置命令的接口,相当于人按下遥控器的按钮
    内含RunCommand运行命令的接口,它调用了命令接口的Execute执行函数

遥控器上的那些按钮,
    不同的按钮对应电视机的不同操作。
    抽象命令角色由一个命令接口来扮演,
    有三个具体的命令类实现了抽象命令接口,
    这三个具体命令类分别代表三种操作:
    打开电视机、关闭电视机和切换频道。

显然,电视机遥控器就是一个典型的命令模式应用实例。
*/




// 接收者对象, 电视才是真正命令的执行者
class Television
{
public :
    void Open( )       // 打开电视
    {
        std::cout <<"打开电视" <<std::endl;
    }

    void Close( )      // 关闭电视
    {
        std::cout <<"关闭电视" <<std::endl;
    }

    void Change( )     // 切换频道
    {
        std::cout <<"更换频道" <<std::endl;
    }
};


class Command
{
public :
    virtual void Execute( ) = 0;         // 执行的接口
};

// 打开电视的命令
class OpenCommand : public Command
{
public :
    OpenCommand(Television *tv)
    {
        m_tv = tv;
    }

    void Execute( )         // 执行的接口
    {
        //std::cout <<"打开电视" <<std::endl;
        m_tv->Open( );
    }
protected :
    Television *m_tv;
};

// 关闭电视的命令
class CloseCommand : public Command
{
public :
    CloseCommand(Television *tv)
    {
        m_tv = tv;
    }
    void Execute( )         // 执行的接口
    {
        //std::cout <<"关闭电视" <<std::endl;
        m_tv->Close( );
    }
protected :
    Television *m_tv;
};

// 更换频道的命令
class ChangeCommand : public Command
{
public :
    ChangeCommand(Television *tv)
    {
        m_tv = tv;
    }
    void Execute( )         // 执行的接口
    {
        //std::cout <<"更换频道" <<std::endl;
        m_tv->Change( );
    }
protected :
    Television *m_tv;
};

// Invoker请求发送者
// 要求命令对象执行请求,
// 通常会持有命令对象,可以持有很多的命令对象
class Control
{
public :
    void SetCommand(Command *command)
    {
       this->m_command = command;
    }

    void RunCommand( )
    {
        m_command->Execute();
    }

protected:
    Command *m_command;

};

// 主程序其实就相当于我们人
int main( )
{
    // 我们手里有一个遥控器
    Control *control = new Control;

    // 家里有一个大彩电
    Television *tv = new Television;

    /// 首先我们打开电视机
    // 创建一个打开的命令, 这个命令只操纵tv这个对象
    Command *openCommand = new OpenCommand(tv);
    control->SetCommand(openCommand);
    control->RunCommand( );
    delete openCommand;


    // 换了好久频道也没找到好看的, 郁闷的关掉电视机
    // 创建一个更换频道的命令,这个命令只操纵tv这个对象
    Command *changeCommand = new ChangeCommand(tv);
    control->SetCommand(changeCommand);
    control->RunCommand( );
    delete changeCommand;

    // 换了好久频道也没找到好看的, 郁闷的关掉电视机
    // 创建一个关闭的命令, 这个命令只操纵tv这个对象
    Command *closeCommand = new CloseCommand(tv);
    control->SetCommand(closeCommand);
    control->RunCommand( );
    delete closeCommand;

    delete tv;
    delete control;
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值