• 设计模式(七):命令模式


      命令模式的定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

      怎么理解呢,举个遥控器的例子,但是这个 遥控器上面的按钮,跟普通不一样。简单来说,就是有分别控制电视开关,电灯开关,风扇开关,空调开关等的按钮。普通情况下,如果你对遥控器编程,那么就会通过遥控器对象,来分别调用电视对象的开关方法,或者风扇对象的开关方法,或者空调对象的开关方法。这样,就会有个if 语句来判断,是调用哪一个对象的方法。命令模式,就是将此时的开关电器的方法抽象出来,进行封装。只要遥控器中存放了开关电器的请求的对象就可以了。代码如下:

    #include <iostream>
    #include <vector>
    
    #include <assert.h>
    
    using namespace std;
    
    enum pos { 
        LIGHT_POSITION,
        CEILING_FAN_POSITION,
        GARAGE_DOOR_POSITION,
        STEREO_POSITION
     };
    
    
    class Light
    {
    public:
        Light() : status( false ){}
        ~Light(){}
    
        void on()
        {
            status = true;
        }
    
        void off()
        {
            status = false;
        }
    
        bool GetLightStatus()
        {
            return status;
        }
    
    private:
        bool status;
        /* data */
    };
    
    class Command
    {
    public:
        Command(){}
        ~Command(){}
    
        virtual void excute(){}
        /* data */
    };
    
    class LightOnCommand : public Command
    {
    public:
        LightOnCommand( Light &li ) : light( &li ) {}
        ~LightOnCommand(){}
    
        void excute()
        {
            light->on();
        }
    
    private:
        Light *light;
    
        /* data */
    };
    
    class LightOffCommand : public Command
    {
    public:
        LightOffCommand( Light &li ) : light( &li ) {}
        ~LightOffCommand(){}
    
        void excute()
        {
            light->off();
        }
    private:
        Light *light;
    
        /* data */
    };
    
    class SimpleRemoteControl
    {
    public:
        SimpleRemoteControl(){}
        ~SimpleRemoteControl(){}
    
        void SetCommand( Command &lon, Command &lof )
        {
            onCommand.push_back( &lon );
            offCommand.push_back( &lof );
        }
    
        void LightOnButtonWasPressed( int slot )
        {
            onCommand[slot]->excute();
        }
    
        void LightOffButtonWasPressed( int slot )
        {
            offCommand[slot]->excute();
        }
    
    private:
        vector<Command*> onCommand;
        vector<Command*> offCommand;
    
        /* data */
    };
    
    void TestLight()
    {
        Light light;
        light.on();
        assert( true == light.GetLightStatus() );
    }
    
    void TestCommandPartenLightOnCommand()
    {
    
        Light light;
        LightOnCommand lo( light );
        lo.excute();
        assert( true == light.GetLightStatus() );
    
        LightOffCommand lof( light );
        lof.excute();
        assert( false == light.GetLightStatus() );
    
    }
    
    void TestCommandParternClient()
    {
        Light light;
        LightOnCommand lon( light );
        LightOffCommand lof( light );
    
    
        SimpleRemoteControl simpleRemoteControl;
        simpleRemoteControl.SetCommand( lon, lof );
        simpleRemoteControl.LightOnButtonWasPressed( LIGHT_POSITION );
        assert( true == light.GetLightStatus() );
        simpleRemoteControl.LightOffButtonWasPressed( LIGHT_POSITION );
        assert( false == light.GetLightStatus() );
    
    }
    
    void TestCommandParten()
    {
        TestLight();
        TestCommandPartenLightOnCommand();
        TestCommandParternClient();
    }
    
    
    int main()
    {
        TestCommandParten();
        return 0;
    }

      其中,枚举的pos为各个电器的开关在遥控器上面的位置。Light为灯的类,其中实现了具体的打开方法on(),关闭方法off(),并且存储了目前的灯所处的状态。

      接下来的command类为所有电器开关的父类,可以派生出各个电器开关请求的子类,如LightOnCommand和LightOnCommand两个子类。这两个子类接受电器实例作为初始化参数,excute方法调用电器实例的具体开关请求。

      前面这部分,主要将电器实例的开关请求进行了封装,后续的操作只要针对command来操作就可以了,在程序执行过程中,会根据具体是哪个电器开关请求来动态调用哪个excute方法。

      SimpleRemoteControl就是我们要的客户端类,即遥控器。遥控器中我们用vector来存储请求实例的指针,通过SetCommand方法来存入具体的电器开关请求。LightOnButtonWasPressed则在按下某个位置的按钮时,调用具体的excute方法。

  • 相关阅读:
    Kubernetes滚动更新介绍及使用-minReadySeconds
    Office 365 – SharePoint 2013 Online 与Office相关的应用
    Office 365 – SharePoint 2013 Online 中添加域和域名
    Office 365
    Office 365 – SharePoint 2013 Online 之WebPart开发、部署教程
    Office 365
    Office 365
    信仰坚持!程序员也有春天!
    SharePoint 2013 日历重叠功能简介
    SharePoint 2013 使用 PowerShell 更新用户
  • 原文地址:https://www.cnblogs.com/bracken/p/3019413.html
Copyright © 2020-2023  润新知