设计模式(六):命令模式
定义:
·将请求分装为对象,将请求和执行分开,可以用不同的请求对客户参数化。可以对请求排队、通过或否决、记录日志、撤销或重做。
·通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
主要解决:
·在软件系统中,对行为请求者和行为实现者进行松耦。
何时使用:
·基于敏捷开发原则,不要给代码添加基于猜测而实际不需要的功能,在需要的时候通过重构实现
以代码为例:
类关系图如下
一、设计Receiver类
被命令类接受请求后真正的执行对象
#include <iostream>
class Receiver
{
public:
void action()
{
std::cout << "Receiver: execute action" << std::endl;
}
// ...
};
二、定义命令接口类Command
class Command
{
public:
virtual ~Command() {}
virtual void execute() = 0;
// ...
protected:
Command() {}
};
三、实现命令接口类ConcreteCommand
Concrete Command通过调用Receiver上的相应操作来实现执行
class ConcreteCommand : public Command
{
public:
ConcreteCommand( Receiver *r ) : receiver( r ) {}
~ConcreteCommand()
{
if ( receiver )
{
delete receiver;
}
}
void execute()
{
receiver->action();
}
// ...
private:
Receiver *receiver;
// ...
};
四、定义Invoker类
Invoker类要求命令执行请求,即使用命令对象的入口
class Invoker
{
public:
void set( Command *c )//
{
command = c;
}
void confirm()
{
if ( command )//如果命令存在,即执行命令
{
command->execute();
}
}
// ...
private:
Command *command;
// ...
};
五、设计main函数
int main()
{
ConcreteCommand command( new Receiver() );//创建一个命令同时实例化一个执行的接收者类
Invoker invoker;//声明一个命令请求
invoker.set( &command );//请求一个命令
invoker.confirm();//执行命令
return 0;
}
按照我们到餐厅点餐来理解,叫服务员invoker点这个菜,即发出命令Command,服务员把命令传递给后厨,就开始进行配菜,即执行Receiver。
命令模式的优缺点:
优点:
1、降低了系统耦合度。
2、新的命令可以很容易添加到系统中去。
缺点:
1、使用命令模式可能会导致某些系统有过多的具体命令类。