首页 > 代码库 > 命令模式

命令模式

将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。

   在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

Command模式可应用于
a)整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。
b)调用前后需要对调用参数进行某些处理。
c)调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

Command模式有如下效果:
a)将调用操作的对象和知道如何实现该操作的对象解耦。
b)Command是头等对象。他们可以像其他对象一样被操作和扩展。
c)你可将多个命令装配成一个符合命令。
d)增加新的Command很容易,因为这无需改变现有的类。




#include <iostream>

#include<map>
#include<string>
using namespace std;
class HouseholdAppliances
{
    public :
    string description;
    void on()
    {
        cout<<description+" light is on"<<endl;
    }
    void off()
    {
        cout<<description+" light is off"<<endl;
    }
};
class Light:public HouseholdAppliances
{
    public:
    Light(string s)
    {
        description=s;
    }
};


struct Command
{
  virtual void excute()=0;
  virtual void undo()=0;
 // virtual void getName()=0;


};
class LightOnCommand :public Command
{
   Light *light;
   public:
   LightOnCommand(Light *light)
   {
       this->light=light;
   }
   void excute()
   {
       light->on();
   }
   void undo()
   {
       light->off();
   }
};
class LightOffCommand:public Command
{
    Light *light;
    public:
    LightOffCommand(Light *lighT)
    {
        light=lighT;
    }
    void excute()
    {
        light->off();
    }
    void undo()
    {
        light->on();
    }
};
class CellingFan:public HouseholdAppliances
{
    public:
    CellingFan(string s)
    {
        description=s;
    }
};
class CellingFanOnCommand:public Command
{
  CellingFan *cell;
  public :
  CellingFanOnCommand(CellingFan *Cell)
  {
      cell=Cell;
  }
  void excute()
  {
      cell->on();
  }
  void undo()
  {
      cell->off();
  }
};
class CellingFanOffCommand:public Command
{
    CellingFan *cell;
    public:
    CellingFanOffCommand(CellingFan *Cell)
    {
        cell=Cell;
    }
    void excute()
    {
        cell->off();
    }
    void undo()
    {
        cell->on();
    }
};
class Stereo:public HouseholdAppliances
{
  public:
  Stereo(string s)
  {
      description=s;
  }
  void setVolume(int temperature)
  {
      cout<<description+"volume set to "<<temperature<<endl;
  }
  void setCD()
  {
      cout<<description+"is set for CD input"<<endl;
  }
};
class StereoOnCommand:public Command
{
    Stereo *s;
    public:
    StereoOnCommand(Stereo *S)
    {
        s=S;
    }
    void excute()
    {
        s->on();
    }
    void undo()
    {
        s->off();
    }
};
class StereoOffCommand:public Command
{
    Stereo *s;
    public:
    StereoOffCommand(Stereo *S)
    {
        s=S;
    }
    void excute()
    {
        s->off();
    }
    void undo()
    {
        s->on();
    }
};
class NoCommand:public Command
{
    public:
    void excute(){};
    void undo(){};


};
class RemoteControlWithUndo
{


    map<int,Command*>onmap;
    map<int,Command*>offmap;
    Command *undoCommand;
    public :
    RemoteControlWithUndo()
    {
       Command *noCommand=new NoCommand();
       for(int i=0;i<7;i++)
       {
           onmap[i]=noCommand;
           offmap[i]=noCommand;
       }
        undoCommand=noCommand;
    }
    void setCommand(int slot,Command *onCommand,Command *offCommand)
    {
        onmap[slot]=onCommand;
        offmap[slot]=offCommand;
    }
    void onButtonWasPushed(int slot)
    {
        onmap[slot]->excute();
        undoCommand=onmap[slot];
    }
    void offButtonWasPushed(int slot)
    {
        offmap[slot]->excute();
        undoCommand=offmap[slot];
    }
    void undoButtonWasPushed()
    {
        undoCommand->undo();
    }
   /* string tostring()
    {
        string s;
        //vector<string>s1;
        cout<<"\n------Remote COntrol ------\n";
        for(int i=0;i<onmap.size();i++)
        {
            cout<<"[slot"<<i<<"] "<<onmap[i]
        }


    }*/
};
//1 ?òμ¥
/*class SimpleRemoteControl
{
    Command *slot;
    public :
    SimpleRemoteControl(){}
     void setCommand(Command *command)
    {
        slot=command;
    }
    void buttonWasPressed()
    {
        slot->excute();
    }
};*/


int main()
{
/*SimpleRemoteControl *re=new SimpleRemoteControl();
Light *light=new Light("living room");
LightOnCommand *lit=new LightOnCommand(light);
re->setCommand(lit);
re->buttonWasPressed();*/
RemoteControlWithUndo *remotecotrol=new RemoteControlWithUndo();
Light *livingRoomLight=new Light("Living Room");
LightOnCommand *livingroomlighton=new LightOnCommand(livingRoomLight);
LightOffCommand *livingRoomLightoff=new LightOffCommand(livingRoomLight);
remotecotrol->setCommand(0,livingroomlighton,livingRoomLightoff);
remotecotrol->onButtonWasPushed(0);
remotecotrol->offButtonWasPushed(0);
//cout<<remotecotrol<<endl;
cout<<"the next is undo method"<<endl;
remotecotrol->undoButtonWasPushed();
remotecotrol->offButtonWasPushed(0);
remotecotrol->onButtonWasPushed(0);
//cout<<remotecotrol<<endl;
cout<<"the last is undo method"<<endl;
remotecotrol->undoButtonWasPushed();
    return 0;

}