命令模式

  1. 命令模式:将"请求"封装成对象,以便使用不同的请求队列或者日志来参数化其它对象。命令模式也支持可撤销的操作。(常用在,队列,日志和支持撤销操作)
  2. 命令模式将发出请求的对象和执行请求的对象解耦。
  3. 在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接收者和一个或一组动作。
  4. 调用者可以接受命令当做参数,甚至在运行时动态地进行

例子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UojF3bOw-1663215832606)(img/order.png)]


  class Light{
   public:
    void on(){
        cout<<" light on"<<endl;
    }
    void off(){
        cout<<"light off"<<endl;
    } 
   }; 

class Command{
    public:
        virtual ~Command(){};
      
        virtual void execute()=0;
        virtual void undo()=0;
};

class LightOnCommand:public Command{
    public:
        LightOnCommand(Light* light):m_light(light){}
        virtual void execute(){
            if(m_light){
                m_light->on();
            }   
        };
        virtual void undo(){
            if(m_light){
                m_light->off();
            }   
        };
    private:
        Light* m_light; 
};


class LightOffCommand:public Command{
    public:
        LightOffCommand(Light* light):m_light(light){}
        virtual void execute(){
            if(m_light){
                m_light->off();
            }   
        };
        virtual void undo(){
            if(m_light){
                m_light->on();
            }   
        };
    private:
        Light* m_light; 
};

class SimpleRemoteControl{
    private:
        Command* m_command;
    public:
        SimpleRemoteControl(Command* command):m_command(command){}
        void buttonPressed(){
            if(m_command){
                m_command->execute();
            }
        }

        void setCommand(Command* command){
            m_command=command;
        }
        ~SimpleRemoteControl(){
            if(m_command){
                delete m_command;
                m_command=nullptr;
            }
        }

        void undo(){
            m_command->undo();
        }
};

class CeilingFan{
    public:
        static int HIGH;
        static int MEDIUM;
        static int LOW;
        static int OFF;
        string m_location;
        int speed;
    CeilingFan(){};
    CeilingFan(string location):m_location(location){

    }
    void high(){
        speed=HIGH;
        cout<<" ceilingfan high"<<endl;
    }       
    void medium(){
        speed=MEDIUM;
        cout<<" ceilingfan medium"<<endl;
    }       
    void low(){
        speed=LOW;
        cout<<" ceilingfan low"<<endl;
    }       
    void off(){
        speed=OFF;
        cout<<" ceilingfan off"<<endl;
    }       
    int getSpeed(){
        return speed;
    }       

};
int CeilingFan::HIGH = 3;
int CeilingFan::MEDIUM=2;
int CeilingFan::LOW=1;
int CeilingFan::OFF=0;


class CeilingHighCommand:public Command{
    public:
        CeilingHighCommand(CeilingFan* ceilingfan):m_ceilingfan(ceilingfan){}
        
        virtual void execute(){
       
            if(m_ceilingfan){
                prevSpeed = m_ceilingfan->getSpeed();       
                m_ceilingfan->high();
            }
       
        };
        virtual void undo(){
            if(prevSpeed==CeilingFan::HIGH){
                m_ceilingfan->high();
            }
            else if(prevSpeed==CeilingFan::MEDIUM){
                m_ceilingfan->medium();
            }
            else if(prevSpeed==CeilingFan::LOW){
                m_ceilingfan->low();
            }
            else if(prevSpeed==CeilingFan::OFF){
                m_ceilingfan->off();
            }
        
        };
        ~CeilingHighCommand(){
            if(m_ceilingfan){
                delete m_ceilingfan;
                m_ceilingfan=nullptr;
            }
        }
    private:
    CeilingFan* m_ceilingfan=nullptr;
    int prevSpeed=0;  //记录风扇之前的速度 

};


class CeilingOffCommand:public Command{
    public:
        CeilingOffCommand(CeilingFan* ceilingfan):m_ceilingfan(ceilingfan){}
        
        virtual void execute(){
            if(m_ceilingfan){
                prevSpeed = m_ceilingfan->getSpeed();       
                m_ceilingfan->off();
            }
       
        };
        virtual void undo(){
            if(prevSpeed==CeilingFan::HIGH){
                m_ceilingfan->high();
            }
            else if(prevSpeed==CeilingFan::MEDIUM){
                m_ceilingfan->medium();
            }
            else if(prevSpeed==CeilingFan::LOW){
                m_ceilingfan->low();
            }
            else if(prevSpeed==CeilingFan::OFF){
                m_ceilingfan->off();
            }
        
        };
        ~CeilingOffCommand(){
            if(m_ceilingfan){
                delete m_ceilingfan;
                m_ceilingfan=nullptr;
            }
        }
    private:
    CeilingFan* m_ceilingfan=nullptr;
    int prevSpeed=0;  //记录风扇之前的速度 

};


int main(){

SimpleRemoteControl* control = new SimpleRemoteControl(nullptr);

Light* light = new Light;
LightOffCommand* lightoff = new LightOffCommand(light);
LightOnCommand* lighton = new LightOnCommand(light);

control->setCommand(lighton);
control->buttonPressed();
control->undo();
cout<<endl;
control->setCommand(lightoff);
control->buttonPressed();
control->undo();
cout<<endl;

CeilingFan* ceilingfan = new CeilingFan;
CeilingHighCommand* ceilinghighcommand = new CeilingHighCommand(ceilingfan);
CeilingOffCommand* ceilingoff = new CeilingOffCommand(ceilingfan);

control->setCommand(ceilinghighcommand);
control->buttonPressed();
control->undo();
cout<<endl;
control->setCommand(ceilingoff);
control->buttonPressed();
control->undo();

system("pause");
return 0;

}

更多推荐