定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
命令模式也有四个角色:分别是
命令接口(Command):一般是用于对外公布一个excute方法用来执行命令
具体命令类(ConcreteCommand):一般实现命令接口,重写excute方法,声明具体的命令(如开灯,关灯之类的命令)
请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
当我们调用时,执行的时序首先是调用者类,然后是命令类,最后是接收者类。也就是说一条命令的执行被分成了三步,它的耦合度要比把所有的操作都封装到一个类中要低的多,而这也正是命令模式的精髓所在:把命令的调用者与执行者分开,使双方不必关心对方是如何操作的。
就比如餐厅点餐的例子:客人(客户端),在菜单上写下要吃的菜(具体命令),交给厨师(具体执行者)。客人不需要知道菜是怎么制作的,我只需要知道各种命令(各种菜),把命令交给具体执行者就行了。
下面是Java代码演示:
接收者角色类
public class Receiver {
/**
* 真正执行命令相应的操作
*/
public void action(){
System.out.println("执行操作");
}
}
抽象命令角色类
public interface Command {
/**
* 执行方法
*/
void execute();
}
具体命令角色类
public class ConcreteCommand implements Command {
//持有相应的接收者对象
private Receiver receiver = null;
/**
* 构造方法
*/
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
receiver.action();
}
}
请求者角色类
public class Invoker {
/**
* 持有命令对象
*/
private Command command = null;
/**
* 构造方法
*/
public Invoker(Command command){
this.command = command;
}
/**
* 行动方法
*/
public void action(){
command.execute();
}
}
客户端角色类
public class Client {
public static void main(String[] args) {
//创建接收者
Receiver receiver = new Receiver();
//创建命令对象,设定它的接收者
Command command = new ConcreteCommand(receiver);
//创建请求者,把命令对象设置进去
Invoker invoker = new Invoker(command);
//执行方法
invoker.action();
}
}
其实我感觉在代码上,这个模式有点像是对象的适配器模式,都是new一个对象作为初始化参数,然后调用方法。
命令模式还有点像策略模式,策略模式有一个上下文对象,命令模式就有一个执行者。都是为了松耦合。但是策略模式是为了通过不同的算法做同一件事情,例如排序,而命令模式是通过不同的命令做不同的事情。两者是有本质区别的。
–我是“道祖且长”,一个在互联网"苟且偷生"的Java程序员
“有任何问题,可评论,我看到就会回复”