將「請求」封裝為物件,使發送者與接收者解耦。支援:請求排隊、撤銷/重做、巨集命令、交易行為、進度條等。
execute()execute() 呼叫 receiver.action()execute()// 1. 命令介面
interface Command { void execute(); }
// 2. 接收者
class Light {
public void on() { System.out.println("燈開啟"); }
public void off() { System.out.println("燈關閉"); }
}
// 3. 具體命令
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
@Override public void execute() { light.on(); }
}
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) { this.light = light; }
@Override public void execute() { light.off(); }
}
// 4. 調用者(支援撤銷)
class RemoteControl {
private List<Command> history = new ArrayList<>();
private Command lastCommand;
public void setCommand(Command cmd) { this.lastCommand = cmd; }
public void pressButton() {
lastCommand.execute();
history.add(lastCommand);
}
public void undo() {
if (!history.isEmpty()) {
// 需命令支援 unexecute() 或儲存狀態(備忘錄模式)
System.out.println("撤銷上一指令");
}
}
}
// 5. 客戶端組裝
public class Demo {
public static void main(String[] args) {
Light light = new Light();
RemoteControl remote = new RemoteControl();
remote.setCommand(new LightOnCommand(light));
remote.pressButton(); // 燈開啟
remote.setCommand(new LightOffCommand(light));
remote.pressButton(); // 燈關閉
remote.undo(); // 撤銷
}
}
interface UndoableCommand extends Command {
void unexecute(); // 或 restore(Memento m)
}
class LightOnCommand implements UndoableCommand {
private Light light;
private boolean prevState; // 備忘錄狀態
public LightOnCommand(Light light) { this.light = light; }
@Override public void execute() {
prevState = light.isOn();
light.on();
}
@Override public void unexecute() {
if (prevState) light.on(); else light.off();
}
}
Action、JavaFX EventHandler)TransactionCommand 封裝業務邏輯,支援回滾ScheduledExecutorService 執行 Runnable 命令Action、Spring CommandLineRunner 皆為命令模式變體| 優點 | 缺點 |
|---|---|
| 解耦發送者/接收者 | 類別數量增加 |
| 易於新增命令、組合巨集命令 | 過度使用導致間接層次過深 |
| 支援撤銷、佇列、日誌、交易 | 簡單場景下屬過度設計 |
命令模式是行為型模式中最具工程落地價值者之一,配合備忘錄模式可構建完整的撤銷/重做機制。