一、核心定義與目標
命令模式通過對象化請求,將操作的具體實現細節隱藏在命令對象中,使得調用者(Invoker)無需直接與接收者(Receiver)交互,僅需通過命令對象間接調用。這種解耦設計支持以下功能:
- 請求隊列化:命令對象可存儲、傳遞并按需執行。
- 撤銷與重做:通過記錄命令歷史實現操作回滾。
- 日志記錄與事務支持:便于追蹤和恢復系統狀態。
二、模式結構與角色
命令模式涉及以下核心角色:
- Command(抽象命令接口)
定義執行命令的統一接口,通常包含execute()
方法。public interface Command { void execute(); }
- ConcreteCommand(具體命令類)
實現Command
接口,持有接收者(Receiver)的引用,并調用其具體方法。public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) { this.light = light; }public void execute() { light.turnOn(); } }
- Receiver(接收者)
實際執行操作的對象,例如電燈、音響設備等。public class Light {public void turnOn() { System.out.println("開燈"); } }
- Invoker(調用者)
負責觸發命令的執行,但不關心命令的具體實現。public class RemoteControl {private Command command;public void setCommand(Command command) { this.command = command; }public void pressButton() { command.execute(); } }
- Client(客戶端)
創建具體命令對象并關聯接收者,將其傳遞給調用者。
三、代碼示例與實現
場景:遙控器控制電燈
- 定義接收者
class Light {public void on() { System.out.println("燈開啟"); }public void off() { System.out.println("燈關閉"); } }
- 實現具體命令
class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) { this.light = light; }public void execute() { light.on(); } }
- 調用者與客戶端
結果:通過調用者間接控制接收者,實現解耦。public class Client {public static void main(String[] args) {Light light = new Light();Command command = new LightOnCommand(light);RemoteControl control = new RemoteControl();control.setCommand(command);control.pressButton(); // 輸出:燈開啟} }
四、高級應用場景
- 宏命令(Macro Command)
將多個命令組合成一個復合命令,例如批量執行操作:class MacroCommand implements Command {private List commands = new ArrayList<>();public void add(Command cmd) { commands.add(cmd); }public void execute() { commands.forEach(Command::execute); } }
- 撤銷與重做(Undo/Redo)
通過擴展命令對象的undo()
方法實現撤銷功能:public interface UndoableCommand extends Command {void undo(); }
- 異步命令隊列
結合線程池處理異步任務,提升系統吞吐量。
五、優缺點分析
優點 | 缺點 |
---|---|
解耦請求發送者與接收者,提升靈活性 | 可能導致類爆炸問題(每個命令需獨立類) |
支持擴展新命令,符合開閉原則 | 增加系統復雜度,需額外管理命令對象 |
便于實現撤銷、日志記錄等高級功能 | 過度設計風險,簡單場景可能不必要 |
六、適用場景
- 需要將請求參數化或延遲執行(如GUI按鈕點擊)。
- 需支持撤銷/重做操作(如文本編輯器)。
- 系統需記錄操作日志或實現事務管理。
七、與其他模式的對比
策略模式:關注算法替換,而命令模式關注請求封裝。
- 觀察者模式:通過訂閱-發布機制解耦,而命令模式通過對象化請求解耦。
總結
命令模式通過對象化請求實現了靈活的調用機制,是構建可擴展、可維護系統的利器。但在實際應用中需權衡其復雜性,避免濫用。結合具體場景(如撤銷操作、異步任務)選擇是否引入該模式,可顯著提升代碼的解耦性與擴展性。