目录
前言
UML
plantuml
类图
实战代码
模板
Command
Invoker
Receiver
Client
前言
命令模式解耦了命令请求者(Invoker)和命令执行者(receiver),使得 Invoker 不再直接引用 receiver,而是依赖于抽象的命令接口。具体的命令类则直接引用 receiver,通过调用 receiver 的方法来执行命令。
解耦之后,具体命令的增删改不再影响 Invoker,同时,抽象出来的命令请求还能队列化,从而实现撤销和重试功能,或做排列组合合成复杂的命令。
在 Invoker 中,也体现了桥接模式的思想,将命令的抽象和具体的实现分离,使 Invoker 中命令的添加和扩展更加简单。不过具体的命令类并不直接实现处理逻辑,而是交给了 receiver 来实现,这也是命令模式和桥接模式最主要的区别。
UML
plantuml
@startuml 'https://plantuml.com/class-diagram interface Command { + execute() : void } class CommandA { - receiver : Receiver + CommandA(Receiver) + execute() : void } class CommandB { - receiver : Receiver + CommandB(Receiver) + execute() : void } class Receiver { + executeA() : void + executeB() : void } class Invoker { - commands : List<Command> + addCommand(Command) : void + execute(Command) : void + executes() : void } class Client {} Command <|.. CommandA Command <|.. CommandB CommandA "1" --> "1" Receiver CommandB "1" --> "1" Receiver Invoker "1" --> "n" Command Client ..> Invoker Client ..> Command @enduml
类图
实战代码
模板
Command
public interface Command {
void execute();
}
public class ConcreteCommand1 implements Command {
private Receiver receiver;
public ConcreteCommand1(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.execute1();
}
}
public class ConcreteCommand2 implements Command {
private Receiver receiver;
public ConcreteCommand2(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.execute2();
}
}
Invoker
public class Invoker {
private List<Command> commands = new ArrayList<Command>();
public void addCommand(Command command){
commands.add(command);
}
public void execute(Command command){
command.execute();
}
public void executes(){
for(Command command : commands){
command.execute();
}
commands.clear();
}
}
Receiver
public class Receiver {
public void execute1() {
System.out.println("execute1.");
}
public void execute2() {
System.out.println("execute2.");
}
}
Client
public class Test {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Invoker invoker = new Invoker();
invoker.execute(new Command1(receiver));
invoker.addAction(new Command1(receiver));
invoker.addAction(new Command2(receiver));
invoker.executes();
}
}