命令模式 屬於行為型模式。它將「請求」封裝為一個對象,從而用不同的請求、隊列、日誌來參數化其他對象,並支持可撤銷的操作。核心思想:將「調用者」與「接收者」解耦,請求本身成為一個獨立對象。
execute() (及可選 undo())。execute() 調用接收者方法。execute(),不關心具體實現。
// 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. 調用者:遙控器 (支持撤銷)
public class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand; // 記錄最後一條命令
public RemoteControl(int slots) {
onCommands = new Command[slots];
offCommands = new Command[slots];
// 初始化空命令 (空對象模式)
Command noCommand = new NoCommand();
Arrays.fill(onCommands, noCommand);
Arrays.fill(offCommands, noCommand);
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCmd, Command offCmd) {
onCommands[slot] = onCmd;
offCommands[slot] = offCmd;
}
public void onButtonPressed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonPressed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonPressed() {
undoCommand.undo();
}
}
// 5. 空命令 (避免 null 判斷)
public class NoCommand implements Command {
@Override public void execute() {}
@Override public void undo() {}
}
// 6. 客戶端
public class Client {
public static void main(String[] args) {
RemoteControl remote = new RemoteControl(2);
Light livingRoomLight = new Light();
remote.setCommand(0, new LightOnCommand(livingRoomLight), new LightOffCommand(livingRoomLight));
remote.onButtonPressed(0); // 燈 開啟
remote.offButtonPressed(0); // 燈 關閉
remote.undoButtonPressed(); // 撤銷 -> 燈 開啟
}
}
execute() 循環調用,undo() 逆序調用。Runnable (本質是命令)。Action、JavaFX Command 均為命令模式應用。