首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 命令模式完整教學:解耦請求與執行、支援撤銷/佇列/日誌

     編輯:Java 相關知識

模式定義與核心價值

將「請求」封裝為物件,使發送者與接收者解耦。支援:請求排隊、撤銷/重做、巨集命令、交易行為、進度條等。

角色結構

  • Command:介面,宣告 execute()
  • ConcreteCommand:綁定 Receiver,實作 execute() 呼叫 receiver.action()
  • Receiver:真正執行業務邏輯的物件
  • Invoker:持有命令集合,負責觸發 execute()
  • Client:組裝 Command、Receiver、Invoker

程式碼實作

// 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(); 
    }
}

實務應用場景

  • GUI 按鈕/選單動作(Swing Action、JavaFX EventHandler)
  • 交易系統:TransactionCommand 封裝業務邏輯,支援回滾
  • 任務排程:ScheduledExecutorService 執行 Runnable 命令
  • Struts 2 Action、Spring CommandLineRunner 皆為命令模式變體

優缺點總結

優點缺點
解耦發送者/接收者類別數量增加
易於新增命令、組合巨集命令過度使用導致間接層次過深
支援撤銷、佇列、日誌、交易簡單場景下屬過度設計

命令模式是行為型模式中最具工程落地價值者之一,配合備忘錄模式可構建完整的撤銷/重做機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved