1,接受者作为命令实现类的一个成员(组合的思想),command类的execute方法,执行接受者要执行的动作.
2,一个简单的实例:
3,遥控器实例:
4,增加了unco()方法的实例
2,一个简单的实例:
#include <iostream>
#include <cassert>
#include <memory>
using namespace std;
/*********************Command对象基类************************/
class Command
{
public:
virtual ~Command() = 0;
virtual void execute() const = 0;
};
Command::~Command() {}
/***********具体Command类,封装一个接受者和其行为**********/
class Light //接受者
{
public: Light() {}
public: void on() const
{
std::cout << "Light is on" << std::endl;
}
public: void off() const
{
std::cout << "Light is off" << std::endl;
}
};
class LightOnCommand : public Command
{
public:
explicit LightOnCommand( const Light* light ) :
_light( light )
{
assert( light );
}
void execute() const
{
_light->on();
}
private:
const Light* _light;
};
class LightOffCommand : public Command
{
public:
explicit LightOffCommand( const Light* light ) :
_light( light )
{
assert( light );
}
public: void execute() const
{
_light->off();
}
private:
const Light* _light;
};
class GarageDoor
{
public:
GarageDoor() {}
void up() const
{
cout << "Garage Door is Open" << endl;
}
void down() const
{
cout << "Garage Door is Closed" << endl;
}
void stop() const
{
cout << "Garage Door is Stopped" << endl;
}
void lightOn() const
{
cout << "Garage light is on" << endl;
}
void lightOff() const {
cout << "Garage light is off" << endl;
}
};
class GarageDoorOpenCommand : public Command
{
public:
explicit GarageDoorOpenCommand( const GarageDoor* garageDoor) :
_garageDoor( garageDoor )
{
assert( garageDoor );
}
void execute() const
{
_garageDoor->up();
}
private:
const GarageDoor* _garageDoor;
};
/******************控制类************************/
class SimpleRemoteControl
{
public:
SimpleRemoteControl() :
_slot( 0 )
{}
public: void setCommand( const Command* command )
{
assert( command );
_slot = command;
}
public: void buttonWasPressed() const
{
assert( _slot );
_slot->execute();
}
private:
const Command* _slot;
};
int main()
{
auto_ptr< SimpleRemoteControl > remote( new SimpleRemoteControl() );
auto_ptr< Light > light( new Light() );
auto_ptr< GarageDoor > garageDoor( new GarageDoor() );
auto_ptr< LightOnCommand > lightOn( new LightOnCommand( light.get() ) );
auto_ptr< GarageDoorOpenCommand > garageOpen( new GarageDoorOpenCommand(garageDoor.get() ) );
remote->setCommand( lightOn.get() );
remote->buttonWasPressed();
remote->setCommand( garageOpen.get() );
remote->buttonWasPressed();
return 0;
}
3,遥控器实例:
#include <iostream>
#include <cassert>
#include <memory>
#include <sstream>
#include <typeinfo>
using namespace std;
/*********************Command对象基类************************/
class Command
{
protected:
Command() {}
public:
virtual ~Command() = 0;
virtual void execute() const = 0;
private:
Command( const Command& ); // Disable copy constructor
void operator=( const Command& ); // Disable assignment operator
};
Command::~Command() {}
/**************特殊的空类**********************/
class NoCommand : public Command
{
public:
void execute() const {}
};
/***************接受者及其命令对象***************/
class CeilingFan
{
public:
explicit CeilingFan( const string location ) :
_level( LOW ), _location( location )
{}
void high() const
{
_level = HIGH;
cout << _location.c_str() << " ceiling fan is on high" << endl;
}
void medium() const
{
_level = MEDIUM;
cout << _location.c_str() << " ceiling fan is on medium" << endl;
}
public: void low() const
{
_level = LOW;
cout << _location.c_str() << " ceiling fan is on low" << endl;
}
void off() const
{
_level = 0;
cout << _location.c_str() << " ceiling fan is off" << endl;
}
int getSpeed() const
{
return _level;
}
public:
static const int HIGH = 2;
static const int MEDIUM = 1;
static const int LOW = 0;
private:
mutable int _level;
string _location;
};
class CeilingFanOnCommand : public Command
{
public:
explicit CeilingFanOnCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
}
void execute() const
{
_ceilingFan->high();
}
private:
const CeilingFan* _ceilingFan;
};
class CeilingFanOffCommand : public Command
{
public:
explicit CeilingFanOffCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
}
void execute() const
{
_ceilingFan->off();
}
private:
const CeilingFan* _ceilingFan;
};
class GarageDoor
{
public:
explicit GarageDoor( const string location ) :
_location( location )
{}
void up() const
{
cout << _location.c_str() << " Door is Up" << endl;
}
void down() const
{
cout << _location.c_str() << " Door is Down" << endl;
}
void stop() const
{
cout << _location.c_str() << " Door is Stopped" << endl;
}
void lightOn() const
{
cout << _location.c_str() << " light is on" << endl;
}
void lightOff() const
{
cout << _location.c_str() << " light is off" << endl;
}
private:
string _location;
};
class GarageDoorUpCommand : public Command
{
public:
explicit GarageDoorUpCommand( const GarageDoor* garageDoor ) :
_garageDoor( garageDoor )
{
assert( garageDoor );
}
public: void execute() const {
_garageDoor->up();
}
private:
const GarageDoor* _garageDoor;
};
class GarageDoorDownCommand : public Command
{
public:
explicit GarageDoorDownCommand( const GarageDoor* garageDoor ) :
_garageDoor( garageDoor )
{
assert( garageDoor );
}
void execute() const
{
_garageDoor->down();
}
private:
const GarageDoor* _garageDoor;
};
class Hottub
{
public:
Hottub() :
_on( false ), _temperature( 0 )
{}
void on() const
{
_on = true;
}
void off() const
{
_on = false;
}
void bubblesOn() const
{
if (_on)
{
cout << "Hottub is bubbling!" << endl;
}
}
void bubblesOff() const
{
if (_on) {
cout << "Hottub is not bubbling" << endl;
}
}
void jetsOn() const
{
if (_on) {
cout << "Hottub jets are on" << endl;
}
}
void jetsOff() const
{
if (_on)
{
cout << "Hottub jets are off" << endl;
}
}
void setTemperature( int temperature )
{
assert( temperature >= 0 );
_temperature = temperature;
}
void heat() const
{
_temperature = 105;
cout << "Hottub is heating to a steaming 105 degrees" << endl;
}
void cool() const
{
_temperature = 98;
cout << "Hottub is cooling to 98 degrees" << endl;
}
private:
mutable bool _on;
mutable int _temperature;
};
class HottubOnCommand : public Command
{
public:
explicit HottubOnCommand( const Hottub* hottub ) :
_hottub( hottub )
{
assert( hottub );
}
public: void execute() const
{
_hottub->on();
_hottub->heat();
_hottub->bubblesOn();
}
private:
const Hottub* _hottub;
};
class HottubOffCommand : public Command
{
public:
explicit HottubOffCommand( const Hottub* hottub ) :
_hottub( hottub )
{
assert( hottub );
}
public: void execute() const
{
_hottub->cool();
_hottub->off();
}
private: const Hottub* _hottub;
};
class Light
{
public:
explicit Light( const string location) :
_location( location )
{}
void on() const
{
cout << _location.c_str() << " light is on" << endl;
}
public: void off() const
{
cout << _location.c_str() << " light is off" << endl;
}
private: string _location;
};
class LightOnCommand : public Command
{
public:
explicit LightOnCommand( const Light* light ) :
_light( light )
{
assert( light );
}
void execute() const
{
_light->on();
}
private:
const Light* _light;
};
class LightOffCommand : public Command
{
public:
explicit LightOffCommand( const Light* light ) :
_light( light )
{
assert( light );
}
public: void execute() const
{
_light->off();
}
private:
const Light* _light;
};
class LivingroomLightOnCommand : public Command
{
public:
explicit LivingroomLightOnCommand( const Light* light ) :
_light( light )
{
assert( light );
}
void execute() const
{
_light->on();
}
private:
const Light* _light;
};
class LivingroomLightOffCommand : public Command
{
public:
explicit LivingroomLightOffCommand( const Light* light ) :
_light( light )
{
assert( light );
}
void execute() const {
_light->off();
}
private:
const Light* _light;
};
class Stereo
{
public:
explicit Stereo( string location ) :
_location( location )
{}
void on() const
{
cout << _location.c_str() << " stereo is on" << endl;
}
void off() const
{
cout << _location.c_str() << " stereo is off" << endl;
}
void setCD() const
{
cout << _location.c_str() << " stereo is set for CD input" << endl;
}
void setDVD() const
{
cout << _location.c_str() << " stereo is set for DVD input" << endl;
}
void setRadio() const
{
cout << _location.c_str() << " stereo is set for Radio" << endl;
}
void setVolume(int volume) const
{
assert(volume > 0 && volume < 12);
// code to set the volume
// valid range: 1-11 (after all 11 is better than 10, right?)
cout << _location.c_str() << " Stereo volume set to " << volume << endl;
}
private: string _location;
};
class StereoOnWithCDCommand : public Command
{
public:
explicit StereoOnWithCDCommand( const Stereo* stereo ) :
_stereo( stereo )
{
assert( stereo );
}
void execute() const
{
_stereo->on();
_stereo->setCD();
_stereo->setVolume(11);
}
private:
const Stereo* _stereo;
};
class StereoOffCommand : public Command
{
public:
explicit StereoOffCommand( const Stereo* stereo ) :
_stereo( stereo )
{
assert( stereo );
}
void execute() const
{
_stereo->off();
}
private: const Stereo* _stereo;
};
class RemoteControl
{
public:
RemoteControl()
{
_noCommand = new NoCommand();
for( int i = 0; i < SLOTS; i++ )
{
_onCommands[i] = _noCommand;
_offCommands[i] = _noCommand;
}
}
~RemoteControl()
{
delete _noCommand;
}
void setCommand( int slot, Command* onCommand, Command* offCommand )
{
assert( slot <= SLOTS );
assert( onCommand );
assert ( offCommand );
_onCommands[slot] = onCommand;
_offCommands[slot] = offCommand;
}
void onButtonWasPushed( int slot ) const
{
assert( slot <= SLOTS );
_onCommands[slot]->execute();
}
void offButtonWasPushed( int slot ) const
{
assert( slot <= SLOTS );
_offCommands[slot]->execute();
}
string toString() const
{
stringstream value;
value << "\n------ Remote Control -------\n" << endl;
for( int i = 0; i < SLOTS; i++ )
{
value << "[slot " << i << "] ";
value << typeid( *_onCommands[i] ).name();
value << " ";
value << typeid( *_offCommands[i] ).name();
value << endl;
}
return value.str();
}
private:
RemoteControl( const RemoteControl& ); // Disable copy constructor
void operator=( const RemoteControl& ); // Disable assignment operator
private:
static const int SLOTS = 7;
Command* _onCommands[SLOTS];
Command* _offCommands[SLOTS];
Command* _noCommand;
};
int main()
{
auto_ptr< RemoteControl > remoteControl(
new RemoteControl() );
auto_ptr< Light > livingRoomLight(
new Light( "Living Room" ) );
auto_ptr< Light > kitchenLight(
new Light( "Kitchen" ) );
auto_ptr< CeilingFan > ceilingFan(
new CeilingFan( "Living Room" ) );
auto_ptr< GarageDoor > garageDoor(
new GarageDoor( "Garage" ) );
auto_ptr< Stereo > stereo(
new Stereo( "Living Room" ) );
auto_ptr< LightOnCommand > livingRoomLightOn(
new LightOnCommand( livingRoomLight.get() ) );
auto_ptr< LightOffCommand > livingRoomLightOff(
new LightOffCommand( livingRoomLight.get() ) );
auto_ptr< LightOnCommand > kitchenLightOn(
new LightOnCommand( kitchenLight.get() ) );
auto_ptr< LightOffCommand > kitchenLightOff(
new LightOffCommand( kitchenLight.get() ) );
auto_ptr< CeilingFanOnCommand > ceilingFanOn(
new CeilingFanOnCommand( ceilingFan.get() ) );
auto_ptr< CeilingFanOffCommand > ceilingFanOff(
new CeilingFanOffCommand( ceilingFan.get() ) );
auto_ptr< GarageDoorUpCommand > garageDoorUp(
new GarageDoorUpCommand( garageDoor.get() ) );
auto_ptr< GarageDoorDownCommand > garageDoorDown(
new GarageDoorDownCommand( garageDoor.get() ) );
auto_ptr< StereoOnWithCDCommand > stereoOnWithCD(
new StereoOnWithCDCommand( stereo.get() ) );
auto_ptr< StereoOffCommand > stereoOff(
new StereoOffCommand( stereo.get() ) );
remoteControl->setCommand( 0, livingRoomLightOn.get(), livingRoomLightOff.get() );
remoteControl->setCommand( 1, kitchenLightOn.get(), kitchenLightOff.get() );
remoteControl->setCommand( 2, ceilingFanOn.get(), ceilingFanOff.get() );
remoteControl->setCommand( 3, stereoOnWithCD.get(), stereoOff.get() );
remoteControl->setCommand( 4, garageDoorUp.get(), garageDoorDown.get() );
cout << remoteControl->toString() << endl;
remoteControl->onButtonWasPushed( 0 );
remoteControl->offButtonWasPushed( 0 );
remoteControl->onButtonWasPushed( 1 );
remoteControl->offButtonWasPushed( 1 );
remoteControl->onButtonWasPushed( 2 );
remoteControl->offButtonWasPushed( 2 );
remoteControl->onButtonWasPushed( 3 );
remoteControl->offButtonWasPushed( 3 );
remoteControl->onButtonWasPushed( 4 );
remoteControl->offButtonWasPushed( 4 );
return 0;
}
4,增加了unco()方法的实例
#include <iostream>
#include <cassert>
#include <memory>
#include <sstream>
#include <typeinfo>
using namespace std;
/*********************Command对象基类************************/
class Command
{
protected:
Command() {}
public:
virtual ~Command() = 0;
virtual void execute() const = 0;
virtual void undo() const = 0;
private:
Command( const Command& ); // Disable copy constructor
void operator=( const Command& ); // Disable assignment operator
};
Command::~Command() {}
/**************特殊的空类**********************/
class NoCommand : public Command
{
public:
void execute() const {}
void undo() const {};
};
/***************接受者及其命令对象***************/
class CeilingFan
{
public:
explicit CeilingFan( string location ) :
_speed( OFF ), _location( location )
{}
void high() const
{
_speed = HIGH;
cout << _location.c_str() << " ceiling fan is on high" << endl;
}
void medium() const
{
_speed = MEDIUM;
cout << _location.c_str() << " ceiling fan is on medium" << endl;
}
void low() const
{
_speed = LOW;
cout << _location.c_str() << " ceiling fan is on low" << endl;
}
void off() const
{
_speed = OFF;
cout << _location.c_str() << " ceiling fan is off" << endl;
}
int getSpeed() const
{
return _speed;
}
public:
static const int HIGH = 3;
static const int MEDIUM = 2;
static const int LOW = 1;
static const int OFF = 0;
private:
mutable int _speed;
string _location;
};
class CeilingFanHighCommand : public Command
{
public:
explicit CeilingFanHighCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
_prevSpeed = _ceilingFan->getSpeed();
}
void execute() const
{
_prevSpeed = _ceilingFan->getSpeed();
_ceilingFan->high();
}
void undo() const
{
if( _prevSpeed == CeilingFan::HIGH )
{
_ceilingFan->high();
}
else if( _prevSpeed == CeilingFan::MEDIUM )
{
_ceilingFan->medium();
}
else if( _prevSpeed == CeilingFan::LOW )
{
_ceilingFan->low();
}
else if( _prevSpeed == CeilingFan::OFF )
{
_ceilingFan->off();
}
}
private:
const CeilingFan* _ceilingFan;
mutable int _prevSpeed;
};
class CeilingFanMediumCommand : public Command
{
public:
explicit CeilingFanMediumCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
_prevSpeed = _ceilingFan->getSpeed();
}
void execute() const
{
_prevSpeed = _ceilingFan->getSpeed();
_ceilingFan->medium();
}
void undo() const
{
if( _prevSpeed == CeilingFan::HIGH )
{
_ceilingFan->high();
}
else if( _prevSpeed == CeilingFan::MEDIUM )
{
_ceilingFan->medium();
}
else if( _prevSpeed == CeilingFan::LOW )
{
_ceilingFan->low();
}
else if( _prevSpeed == CeilingFan::OFF )
{
_ceilingFan->off();
}
}
private:
const CeilingFan* _ceilingFan;
mutable int _prevSpeed;
};
class CeilingFanLowCommand : public Command
{
public:
explicit CeilingFanLowCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
_prevSpeed = _ceilingFan->getSpeed();
}
void execute() const
{
_prevSpeed = _ceilingFan->getSpeed();
_ceilingFan->low();
}
void undo() const
{
if( _prevSpeed == CeilingFan::HIGH )
{
_ceilingFan->high();
}
else if( _prevSpeed == CeilingFan::MEDIUM )
{
_ceilingFan->medium();
}
else if( _prevSpeed == CeilingFan::LOW )
{
_ceilingFan->low();
}
else if( _prevSpeed == CeilingFan::OFF )
{
_ceilingFan->off();
}
}
private:
const CeilingFan* _ceilingFan;
mutable int _prevSpeed;
};
class CeilingFanOffCommand :public Command
{
private:
const CeilingFan* _ceilingFan;
mutable int _prevSpeed;
public:
explicit CeilingFanOffCommand( const CeilingFan* ceilingFan ) :
_ceilingFan( ceilingFan )
{
assert( ceilingFan );
_prevSpeed = _ceilingFan->getSpeed();
}
void execute() const
{
_prevSpeed = _ceilingFan->getSpeed();
_ceilingFan->off();
}
void undo() const
{
if( _prevSpeed == CeilingFan::HIGH )
{
_ceilingFan->high();
}
else if( _prevSpeed == CeilingFan::MEDIUM )
{
_ceilingFan->medium();
}
else if( _prevSpeed == CeilingFan::LOW )
{
_ceilingFan->low();
}
else if( _prevSpeed == CeilingFan::OFF )
{
_ceilingFan->off();
}
}
};
class Light
{
public:
explicit Light( const string location ) :
_location( location ), _level( 0 )
{}
void on() const
{
_level = 100;
cout << _location.c_str() << " light is on" << endl;
}
void off() const
{
_level = 0;
cout << _location.c_str() << " light is off" << endl;
}
void dim( int level ) const
{
_level = level;
if( _level == 0 )
{
off();
}
else
{
cout << "Light is dimmed to " << _level << "%" << endl;
}
}
int getLevel() const
{
return _level;
}
private:
string _location;
mutable int _level;
};
class LightOnCommand : public Command
{
public:
explicit LightOnCommand( const Light* light) :
_light(light)
{
assert(light);
}
void execute() const
{
_light->on();
}
void undo() const
{
_light->off();
}
private:
const Light* _light;
};
class LightOffCommand : public Command
{
public:
explicit LightOffCommand( const Light* light ) :
_light( light )
{
assert( light );
}
public: void execute() const
{
_light->off();
}
public: void undo() const
{
_light->on();
}
private:
const Light* _light;
};
class DimmerLightOnCommand : public Command
{
public:
explicit DimmerLightOnCommand( const Light* light ) :
_light( light )
{
assert( light );
_prevLevel = _light->getLevel();
}
void execute() const
{
_prevLevel = _light->getLevel();
_light->dim( 75 );
}
void undo() const
{
_light->dim( _prevLevel );
}
private:
const Light* _light;
mutable int _prevLevel;
};
class DimmerLightOffCommand : public Command
{
public:
explicit DimmerLightOffCommand( const Light* light ) :
_light( light )
{
assert( light );
_prevLevel = _light->getLevel();
}
void execute() const
{
_prevLevel = _light->getLevel();
_light->off();
}
void undo() const
{
_light->dim( _prevLevel );
}
private:
const Light* _light;
mutable int _prevLevel;
};
class RemoteControlWithUndo
{
public:
RemoteControlWithUndo()
{
_noCommand = new NoCommand();
for( int i = 0; i < SLOTS; i++ )
{
_onCommands[i] = _noCommand;
_offCommands[i] = _noCommand;
}
_undoCommand = _noCommand;
}
~RemoteControlWithUndo()
{
delete _noCommand;
}
void setCommand( int slot, Command* onCommand, Command* offCommand )
{
assert( slot <= SLOTS );
assert( onCommand );
assert( offCommand );
_onCommands[slot] = onCommand;
_offCommands[slot] = offCommand;
}
void onButtonWasPushed( int slot ) const
{
assert( slot <= SLOTS );
_onCommands[slot]->execute();
_undoCommand = _onCommands[slot];
}
void offButtonWasPushed( int slot ) const
{
assert( slot <= SLOTS );
_offCommands[slot]->execute();
_undoCommand = _offCommands[slot];
}
void undoButtonWasPushed() const
{
_undoCommand->undo();
}
string toString() const
{
stringstream value;
value << endl << "------ Remote Control -------" << endl;
for( int i = 0; i < SLOTS; i++ )
{
value << "[slot " << i << "] ";
value << typeid( *_onCommands[i] ).name();
value << " ";
value << typeid( *_offCommands[i] ).name();
value << endl;
}
value << "[undo] " << typeid( *_undoCommand ).name() << endl;
return value.str();
}
private:
static const int SLOTS = 7;
Command* _onCommands[SLOTS];
Command* _offCommands[SLOTS];
Command* _noCommand;
mutable Command* _undoCommand;
};
int main()
{
auto_ptr< RemoteControlWithUndo > remoteControl( new RemoteControlWithUndo() );
auto_ptr< Light > livingRoomLight( new Light( "Living Room" ) );
auto_ptr< LightOnCommand > livingRoomLightOn( new LightOnCommand( livingRoomLight.get() ) );
auto_ptr< LightOffCommand > livingRoomLightOff( new LightOffCommand( livingRoomLight.get() ) );
remoteControl->setCommand( 0, livingRoomLightOn.get(), livingRoomLightOff.get() );
remoteControl->onButtonWasPushed( 0 );
remoteControl->offButtonWasPushed( 0 );
remoteControl->onButtonWasPushed( 0 );
cout << remoteControl->toString() << endl;
remoteControl->undoButtonWasPushed();
auto_ptr< CeilingFan > ceilingFan( new CeilingFan( "Living Room" ) );
auto_ptr< CeilingFanMediumCommand > ceilingFanMedium( new CeilingFanMediumCommand( ceilingFan.get() ) );
auto_ptr< CeilingFanHighCommand > ceilingFanHigh( new CeilingFanHighCommand( ceilingFan.get() ) );
auto_ptr< CeilingFanOffCommand > ceilingFanOff( new CeilingFanOffCommand( ceilingFan.get() ) );
remoteControl->setCommand( 0, ceilingFanMedium.get(), ceilingFanOff.get() );
remoteControl->setCommand( 1, ceilingFanHigh.get(), ceilingFanOff.get() );
remoteControl->onButtonWasPushed( 0 );
remoteControl->offButtonWasPushed( 0 );
cout << remoteControl->toString() << endl;
remoteControl->undoButtonWasPushed();
remoteControl->onButtonWasPushed( 1 );
cout << remoteControl->toString() << endl;
remoteControl->undoButtonWasPushed();
return 0;
}