命令模式
将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。它包含请求的发送者、接收者、命令三个部分。
命令模式实例之电视机遥控器
从类图可知, Controller类(发送者)聚合多个命令类,然后通过抽象多态的方式,调用execute来调用具体命令类,从而实现对命令类关联的Television(接收者)的不同控制。
原书上的代码应该是有点问题的,在每个命令类都关联并生成了一个不同的TV接收者类,开机、关机和更换频道不是对同一个TV接收者类进行控制,不是很符合现实逻辑,所以进行了一些改动,将open、close和change命令类构造赋值一个TV接收者的指针,在客户端测试块中进行生成TV接收者类,然后命令类生成的时候传参进去,从而实现了对同一个TV接收者类的控制。
下面是c++版本的实现
接收者类Television
//接收者类Television
class Television{
public:
void open(){
cout << "打开电视机!" << endl;
}
void close(){
cout << "关闭电视机!" << endl;
}
void changeChannel(){
cout << "切换电视频道!" << endl;
}
};
抽象命令类AbstartCommand
//抽象命令类AbstartCommand
class AbstractCommand{
public:
virtual void execute() = 0;
};
具体命令类TVOpenCommand
//具体命令类TVOpenCommand
class TVOpenCommand : public AbstractCommand{
public:
TVOpenCommand(shared_ptr<Television> tv){
this->tv = tv;
}
void execute(){
tv->open();
}
private:
shared_ptr<Television> tv;
};
具体命令类TVCloseCommmand
//具体命令类TVCloseCommmand
class TVCloseCommand : public AbstractCommand{
public:
TVCloseCommand(shared_ptr<Television> tv){
this->tv = tv;
}
void execute(){
tv->close();
}
private:
shared_ptr<Television> tv;
};
具体命令类TVChangeCommmand
//具体命令类TVChangeCommmand
class TVChangeCommand : public AbstractCommand{
public:
TVChangeCommand(shared_ptr<Television> tv){
this->tv = tv;
}
void execute(){
tv->changeChannel();
}
private:
shared_ptr<Television> tv;
};
调用者类Controller
//调用者类Controller
class Controller{
public:
Controller(shared_ptr<AbstractCommand> openCommand,
shared_ptr<AbstractCommand> closeCommand,
shared_ptr<AbstractCommand> changeCommand){
this->openCommand = openCommand;
this->closeCommand = closeCommand;
this->changeCommand = changeCommand;
}
void open(){
openCommand->execute();
}
void change(){
changeCommand->execute();
}
void close(){
closeCommand->execute();
}
private:
shared_ptr<AbstractCommand> openCommand;
shared_ptr<AbstractCommand> closeCommand;
shared_ptr<AbstractCommand> changeCommand;
};
客户端测试
//客户端测试
int main(void){
// 接收者电视机
shared_ptr<Television> tv = make_shared<Television>();
// 命令
shared_ptr<AbstractCommand> openCommand = make_shared<TVOpenCommand>(tv);
shared_ptr<AbstractCommand> closeCommand = make_shared<TVCloseCommand>(tv);
shared_ptr<AbstractCommand> changeCommand = make_shared<TVChangeCommand>(tv);
// 调用者
shared_ptr<Controller> controll = make_shared<Controller>(openCommand,closeCommand,changeCommand);
// 测试
controll->open();
controll->change();
controll->close();
return 0;
}
测试结果