将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。
在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作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;
}