命令模式將「請求」封裝為物件,實現發送者與接收者解耦,支援佇列、日誌、撤銷/重做等進階功能。本文結合 GoF 定義、生活類比、UML 結構與 Java 完整範例,深入剖析此模式精髓。
將請求封裝為物件,使你能用不同請求參數化客戶端、將請求排隊或記錄日誌、支援可撤銷操作。
老闆(Client)發出命令 → 秘書 跑腿傳遞 → 員工 執行實際工作。老闆不需知道誰執行、如何執行;員工不需知道命令來源。秘書負責傳遞、排隊、記錄。

execute()| 優點 | 缺點 |
|---|---|
| 易構建命令佇列 | 可能產生大量具體命令類別 |
| 支援日誌、撤銷/重做 | 增加系統複雜度 |
| 新命令易擴充(OCP) | |
| 接收者可決定是否執行 |
// 1. Command 介面
public interface Command {
void execute();
void undo();
}
// 2. Receiver
public class MP3Player {
public void play() { System.out.println("播放音樂"); }
public void stop() { System.out.println("停止播放"); }
public void next() { System.out.println("下一首"); }
public void prev() { System.out.println("上一首"); }
}
// 3. Concrete Commands
public class PlayCommand implements Command {
private MP3Player player;
public PlayCommand(MP3Player p) { this.player = p; }
public void execute() { player.play(); }
public void undo() { player.stop(); }
}
public class NextCommand implements Command {
private MP3Player player;
public NextCommand(MP3Player p) { this.player = p; }
public void execute() { player.next(); }
public void undo() { player.prev(); }
}
// 4. Invoker
public class RemoteControl {
private Command[] onCommands;
private Command[] offCommands;
private Command lastCommand;
public RemoteControl(int slots) {
onCommands = new Command[slots];
offCommands = new Command[slots];
}
public void setCommand(int slot, Command on, Command off) {
onCommands[slot] = on;
offCommands[slot] = off;
}
public void onButtonPressed(int slot) {
onCommands[slot].execute();
lastCommand = onCommands[slot];
}
public void offButtonPressed(int slot) {
offCommands[slot].execute();
lastCommand = offCommands[slot];
}
public void undoButtonPressed() {
if (lastCommand != null) lastCommand.undo();
}
}
// 5. Client 組裝
public class Main {
public static void main(String[] args) {
MP3Player player = new MP3Player();
RemoteControl remote = new RemoteControl(2);
remote.setCommand(0, new PlayCommand(player), new StopCommand(player));
remote.setCommand(1, new NextCommand(player), new PrevCommand(player));
remote.onButtonPressed(0); // 播放
remote.onButtonPressed(1); // 下一首
remote.undoButtonPressed(); // 撤銷:上一首
}
}
命令模式的核心是「抓住主要矛盾」——將易變的「動作」抽離封裝,讓系統在擴充新功能時不修改既有結構,完美體現開放封閉原則。GoF 四人幫以此模式展示了物件導向設計「封裝變化」的經典智慧。