1.职责链模式 2.命令模式 3.迭代器模式 4.观察者模式 5.策略模式 6.模板方法模式 7.访问者模式 8.中介者模式 9.备忘录模式 10.状态模式
由于学习难度较大或相对用途较少 本章不会讲解7-10四种设计模式
接下来针对以上6种设计模式进行单独讲解
2 命令模式
2.1 定义
将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化。
命令模式将请求的发送者和处理者完全解耦,发送者和处理者之间没有直接的引用关系,发送请求的对象只知道怎么发送请求,而不必知道请求如何被处理。
举例说明:开关会下达开或者关的命令,命令通过电线传播,至于电线连接时灯泡还是风扇,开关完全不知情。
再比如:一般OA系统都会有快捷键指令,自己可以设置某个快捷键具体执行某些能力,用户点击快捷键向系统发送指令,这时候快捷键只是一个命令,具体要执行哪个能力由后台设置的对应关系决定。如下图,设置好功能键代表的功能之后,按下功能键1,这时候只是给系统发送了一个功能键1的命令,但是具体执行打开帮助文档还是最小化到托盘或者是自动截屏,是由后台系统决定,而不是由这个功能键决定。
2.2 UML图
从上面UML图中可以看出
Command为抽象命令类,一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
ConcreteCommand为具体命令类,实现了在抽象命令类中声明的方法,将接收者对象的动作绑定其中。在实现execute()方法时,将调用接收者对象的相关操作(Action)。
Invoker为调用者,即请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的execute()方法,从而实现间接调用请求接收者的相关操作。
Receiver为接收者:接收者执行与请求相关的操作,它具体实现对请求的业务处理。
2.3 代码实现
// 抽象命令类
public interface Command {
void execute();
}
// 具体命令类A
public class ConcreteCommandA implements Command {
private Receiver receiver;
public ConcreteCommandA(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
// 具体命令类B
public class ConcreteCommandB implements Command {
private Receiver receiver;
public ConcreteCommandB(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
// 接收者类
public class Receiver {
public void action() {
System.out.println("Receiver action");
}
}
// 调用者类
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
public class Main {
public static void main(String[] args) {
// 创建接收者对象
Receiver receiver = new Receiver();
// 创建具体命令对象A,将接收者对象传入构造函数中,绑定动作关系
ConcreteCommandA commandA = new ConcreteCommandA(receiver);
// 创建具体命令对象B,将接收者对象传入构造函数中,绑定动作关系
ConcreteCommandB commandB = new ConcreteCommandB(receiver);
// 创建调用者对象,将具体命令对象A传入构造函数中,绑定关系
Invoker invokerA = new Invoker(commandA);
Invoker invokerB = new Invoker(commandB);
// 调用调用者的executeCommand方法,间接调用接收者的相关操作
invokerA.executeCommand();
invokerB.executeCommand();
2.4 拓展
宏命令模式是命令模式+组合模式的实现,其UML图如下所示
其中MarcoCommand充当组合模式中的容器节点,具体command类充当叶子节点,再MarcoCommand中递归调用其子节点。
具体组合模式代码可参考设计模式之结构型模式(三)组合模式 - 掘金 (juejin.cn)本篇文章