行为型-命令模式
2026/1/15大约 2 分钟Java设计模式行为型模式命令模式Java设计模式面向对象架构设计最佳实践代码优化
概述
命令模式(Command Pattern)将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
适用场景
- 需要将请求调用者和请求接收者解耦
- 需要在不同的时间指定请求、将请求排队和执行请求
- 需要支持命令的撤销和恢复操作
- 需要将一组操作组合在一起(宏命令)
角色组成
- Command(抽象命令):声明执行操作的接口
- ConcreteCommand(具体命令):将接收者对象绑定于一个动作
- Invoker(调用者):要求命令执行请求
- Receiver(接收者):知道如何实施与执行请求相关的操作
代码实现
1. 接收者
// 电灯
public class Light {
public void on() {
System.out.println("灯打开了");
}
public void off() {
System.out.println("灯关闭了");
}
}2. 抽象命令
public interface Command {
void execute();
void undo();
}3. 具体命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
### 4. 调用者
```java
public class RemoteControl {
private Command command;
private Stack<Command> history = new Stack<>();
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
history.push(command);
}
public void pressUndo() {
if (!history.isEmpty()) {
Command lastCommand = history.pop();
lastCommand.undo();
}
}
}5. 客户端
public class Client {
public static void main(String[] args) {
Light light = new Light();
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();
remote.setCommand(lightOff);
remote.pressButton();
// 撤销
remote.pressUndo();
}
}# 输出
灯打开了
灯关闭了
灯打开了类图
宏命令
public class MacroCommand implements Command {
private List<Command> commands = new ArrayList<>();
public void addCommand(Command command) {
commands.add(command);
}
@Override
public void execute() {
for (Command command : commands) {
command.execute();
}
}
@Override
public void undo() {
for (int i = commands.size() - 1; i >= 0; i--) {
commands.get(i).undo();
}
}
}JDK 中的应用
java.lang.Runnablejavax.swing.Action
优缺点
优点:
- 降低系统耦合度
- 新的命令可以很容易添加到系统中
- 可以比较容易地设计一个命令队列和宏命令
- 可以方便地实现对请求的撤销和恢复
缺点:
- 可能导致某些系统有过多的具体命令类
