【设计模式】命令

来源:互联网 发布:mac os 最稳定 编辑:程序博客网 时间:2024/06/05 11:20

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

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

命令模式目的用命令类本身将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;//receiverclass 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 controlerint 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:1execute 2:channel increased:2unexecute:channel decreased:1restart command!execute:The TV is off!The TV is on!un execute:do nothing for Restart UnExecute!

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

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

原创粉丝点击