一、概述
1、定义
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。命令模式也叫委派模式。
2、角色
2-1、抽象命令类:一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
2-2、调用者:调用者即请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的execute()方法,从而实现间接调用请求接收者的相关操作。
2-3、请求接收者:接收者执行与请求相关的操作,它具体实现对请求的业务处理。
2-4、具体命令类:具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具体的接收者对象,将接收者对象的动作绑定其中。在实现execute()方法时,将调用接收者对象的相关操作(Action)。
二、代码
抽象命令类
public abstract class Command {
public abstract void execute();
}
对于请求发送者即调用者而言,将针对抽象命令类进行编程,可以通过构造注入或者设值注入的方式在运行时传入具体命令类对象,并在业务方法中调用命令对象的execute()方法,其典型代码如下:
public class Invoker {
private Command command;
//构造注入
public Invoker(Command command) {
this.command = command;
}
//设值注入
public void setCommand(Command command) {
this.command = command;
}
//业务方法,用于调用命令类的execute()方法
public void call() {
command.execute();
}
}
请求接收者Receiver类具体实现对请求的业务处理,它提供了action()方法,用于执行与请求相关的操作,其典型代码如下所示:
public class Receiver {
public void action() {
//具体操作
}
}
具体命令类继承了抽象命令类,它与请求接收者相关联,实现了在抽象命令类中声明的execute()方法,并在实现时调用接收者的请求响应方法action(),其典型代码如下:
public class ConcreteCommand extends Command {
private Receiver receiver = new Receiver(); //维持一个对请求接收者对象的引用
public void execute() {
receiver.action(); //调用请求接收者的业务处理方法action()
}
}
测试类
public class Client {
public static void main(String[] args) {
//命令
Command command = new ConcreteCommand();
//发送者,及携带命令
Invoker invoker = new Invoker(command);
//发送命令
invoker.call();
}
}
思考:为什么命令类要写成抽象类或接口,然后让实现具体命令类?
写成抽象类和接口,可以根据不同对像实现不同的具体命令类。比如大领导发布了一条小领导的命令,小领导接收到命令之后要先喝杯茶再去执行名;大领导发布了一条基层人员命令,小螺螺立马执行命令。这种方式和策略模式有相似之处。
三、总结
1、命令模式将命令发送者和命令接收者解耦,发送者无需关心命令如何被执行。
2、设计到的角色有抽象命令类、具体命令类、发送者、接收者。