命令模式
命令模式是常用的行为型设计模式之一,它在请求的发送者和接收者之间引入了新的命令对象,将请求的发送者和请求的接收者进行解耦,请求发送者通过命令对象简介引用请求接收者,使得系统具有更好的灵活性,可以在不修改现有系统源代码的情况下让相同的发送者对应不同的接收者。
命令模式的本质时对命令进行封装,一个请求对应一个命令,将发出命令的责任和执行命令的责任进行分离,请求放发送者只要求执行发送操作,请求接收者只接收请求执行相应的操作。
定义
将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
结构
- Command抽象命令类。抽象类或者接口,声明了命令执行的execute方法,被请求发送者调用。
- ConcreteCommand具体命令类。实现了execute方法,关联着具体的命令接收者,当调用execute方法时,调用命令接收者的执行方法。
- Invoker调用者。请求发送者,调用命令对象执行功能,它不需要知道具体的命令执行者,在程序运行的时候将命令对象注入,由命令对象调用具体功能。
- Receiver接收者。接收者执行与请求相关的操作,具体实现对请求的业务处理。
示例
package command.basic;
public interface Command {
void execute();
}
package command.basic;
import java.util.Objects;
public class DoorCommand implements Command {
private Door door = new Door();
public void setDoor(Door door) {
this.door = door;
}
@Override
public void execute() {
if (Objects.nonNull(door)) {
door.action();
}
}
}
package command.basic;
import java.util.Objects;
public class LampCommand implements Command {
private Lamp lamp = new Lamp();
public void setLamp(Lamp lamp) {
this.lamp = lamp;
}
@Override
public void execute() {
if (Objects.nonNull(lamp)) {
lamp.action();
}
}
}
package command.basic;
public class Door {
private boolean open = false;
public void action() {
if (open) {
System.out.println("关门");
open = false;
} else {
System.out.println("开门");
open = true;
}
}
}
package command.basic;
public class Lamp {
private boolean bright = false;
public void action() {
if (bright) {
System.out.println("关灯");
bright = false;
} else {
System.out.println("开灯");
bright = true;
}
}
}
package command.basic;
import java.util.Objects;
public class Button {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void invoke() {
if (Objects.nonNull(command)) {
command.execute();
}
}
}
package command.basic;
public class Test {
public static void main(String[] args) {
Button button = new Button();
button.setCommand(new DoorCommand());
button.invoke();
}
}
变体
队列、撤销操作、宏命令
优点
- 降低了代码的耦合度。命令模式将发送命令与执行命令分开,使相同的发送者可以对应不同的执行者,实现解耦。
- 新的命令模式可以很容易地加入到系统中,不会对其他命令产生影响。
- 实现命令队列或组合命令,并且为撤销和恢复操作提供了一种实现方案。
适用场景
- 命令分为发送者和执行者。
- 命令有有多种执行状态
- 命令有多个命令组成,实现复杂的操作