🎯 什麼情境該想到我

當你「想把一個『要做的操作』本身當成物件來對待——好讓它能被排隊、被記錄、被延後執行,或事後被復原」的時候(例如支援 undo/redo、任務佇列、選單與按鈕綁不同動作)。

⚙️ 怎麼用(步驟 / 公式)

意圖:把一個請求封裝成一個物件,藉此讓你可以用不同的請求將客戶端參數化,並支援請求的排隊、記錄與復原。

主要參與者 / 結構:

  • Command(命令介面):宣告 execute()(常再加 undo())。
  • ConcreteCommand(具體命令):綁定一個 Receiver 與一組動作,execute() 時呼叫 Receiver 對應方法。
  • Receiver(接收者):真正知道如何執行工作的物件。
  • Invoker(觸發者):持有命令並在某時機呼叫 execute(),不需知道命令細節。
  • Client:建立具體命令並設定其 Receiver。

做法要點:

  1. 把每一種操作封裝成一個實作 Command 的物件,內含執行所需的 Receiver 與參數。
  2. Invoker 只認得 Command 介面,透過 execute() 觸發,不關心誰做、怎麼做。
  3. 要支援復原時,命令自行記住足以還原的狀態並實作 undo();用一個歷史堆疊記錄執行過的命令。
  4. 命令是物件,因此可被存進佇列、序列化記錄、延後或批次執行。

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

  • 每個操作都獨立一個類別,操作一多會讓類別數量明顯增加。
  • 要做完整 undo/redo 時,命令得妥善保存還原所需狀態,設計成本不低。
  • 若操作很單純、又不需排隊/記錄/復原,直接呼叫就好,別為了模式而包一層。

🔗 相關工具