【设计模式】命令

命令模式,最常应用的场景或许就是各种触发命令的场合。这个通过名称就可以联想,而且还比较容易理解。

而其他诸如回调啊之类的应用场景目前还不是很能体会。

命令模式目的用命令类本身将client和其真正实现者(receiver)进行解耦,从而用户只关心具体的命令,而不去关心其实现。而增加命令,对于现有的receiver和client都可以透明。

而对于命令中的可撤销等感觉也不是必须的。增加这个特性,可能只是为了支持事务等更规范一些。

写了个简单demo。每个命令都可以cancel,而如restart命令,可以认为是后加的。当然新命令,也可以对应新receiver。

/**
 * @file command_test.cpp
 * @author itegel
 * @date 2013/05/27 19:02:26
 * @brief 
 *  
 **/

#include <iostream>
using namespace std;

//receiver
class TV{
    public:
        TV(){
            channel = 0;
        }
        ~TV(){}
        void TurnOn(){
            cout<<"The TV is on!"<<endl;
        }
        void TurnOff(){
            cout<<"The TV is off!"<<endl;
        }
        void IncreaseChannel(){
            channel++;
            cout<<"channel increased:"<<channel<<endl;
        }
        void DecreaseChannel(){
            channel--;
            cout<<"channel decreased:"<<channel<<endl;
        }
    private:
        int channel;
};

class Command{
    public:
        Command(){}
        ~Command(){}
        virtual void Execute() = 0;
        virtual void UnExecute() = 0;
};

class TurnOnCmd : public Command{
    public:
        TurnOnCmd(TV * tv):_tv(tv){}
        ~TurnOnCmd(){}
        virtual void Execute(){
            _tv->TurnOn();
        }
        virtual void UnExecute(){
            _tv->TurnOff();
        }
    private:
        TV * _tv;
};

class TurnOffCmd : public Command{
    public:
        TurnOffCmd(TV * tv):_tv(tv){}
        ~TurnOffCmd(){}
        virtual void Execute(){
            _tv->TurnOff();
        }
        virtual void UnExecute(){
            _tv->TurnOn();
        }
    private:
        TV * _tv;
};

class IncreaseCmd : public Command{
    public:
        IncreaseCmd(TV * tv):_tv(tv){}
        ~IncreaseCmd(){}
        virtual void Execute(){
            _tv->IncreaseChannel();
        }
        virtual void UnExecute(){
            _tv->DecreaseChannel();
        }
    private:
        TV * _tv;
};


class RestartCmd : public Command{
    public:
        RestartCmd(TV * tv):_tv(tv){}
        ~RestartCmd(){}
        virtual void Execute(){
            _tv->TurnOff();
            _tv->TurnOn();
        }
        virtual void UnExecute(){
            cout<<"do nothing for Restart UnExecute!"<<endl;
        }
    private:
        TV * _tv;
};

//client + invoker, user or remote controler
int main(){
    TV * tv = new TV();
    cout<<"Turn on command!"<<endl;
    cout <<"Execute:"<<endl;
    TurnOnCmd * turn_on = new TurnOnCmd(tv);
    turn_on->Execute();
    cout <<"Un Execute:"<<endl;
    turn_on->UnExecute();
    cout<<endl;

    TurnOffCmd * turn_off = new TurnOffCmd(tv);
    cout<<"trun off command!"<<endl;
    cout<<"execute:"<<endl;
    turn_off->Execute();
    cout<<endl;

    IncreaseCmd * increase = new IncreaseCmd(tv);
    cout<<"increase command!"<<endl;
    cout<<"execute1:"<<endl;
    increase->Execute();
    cout<<"execute 2:"<<endl;
    increase->Execute();
    cout<<"unexecute:"<<endl;
    increase->UnExecute();
    cout<<endl;

    RestartCmd * restart = new RestartCmd(tv);
    cout << "restart command!"<<endl;
    cout<< "execute:"<<endl;
    restart->Execute();
    cout<< "un execute:"<<endl;
    restart->UnExecute();
    cout<<endl;

    return 0;
}
执行结果:

Turn on command!
Execute:
The TV is on!
Un Execute:
The TV is off!

trun off command!
execute:
The TV is off!

increase command!
execute1:
channel increased:1
execute 2:
channel increased:2
unexecute:
channel decreased:1

restart command!
execute:
The TV is off!
The TV is on!
un execute:
do nothing for Restart UnExecute!

这里没有实现invoker。实际上加一个invoker,可以更好的隔离command和用户。而一个invoker可以是一个command组合。多个command也可以通过职责链等方式进行链接起来。

命令可以有自己的命令号,客户只知道命令号,而不去关心具体哪个具体命令类执行该命令,更不会关注receiver是怎么实现该命令的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值