目錄
- 情景劇場
- 什么是命令模式
- 優缺點
- 優點
- 缺點
- 使用命令模式的步驟
- 命令模式代碼示例
- 合理使用AI工具自動生成代碼
情景劇場
我們來設想一個場景:
你進入一家餐館,餐館只有老板一個人(老板即廚師)。
“老板,一份小炒肉,不要辣。”
老板收到了你的訂單請求,去后廚做菜了。這時又進來幾位顧客:
“老板,來兩份清炒時蔬,不要辣。”
“老板,我要一份清炒時蔬,多放辣。”
“老板,一份小炒肉,多放辣,打包。”
“老板,我的兩份清炒時蔬改成一份,打包。”
…
當顧客變多,請求也變多,而每個顧客的請求也非常不一樣。老板就很容易分不清誰的需求是什么,做錯菜、上錯菜都是會發生的錯誤。顧客對老板直接提出請求,請求多了很容易導致混亂。這里顧客就是請求的發送者,老板就是請求的接收者,請求者和接收者的“緊耦合”雖然邏輯簡單,但是很容易僵化。
當給餐館加上服務員和訂單,就會不一樣:
顧客走進餐館開始點單,服務員接過顧客的訂單,并將其寫在一張紙上。服務員去廚房,把訂單貼在墻上,訂單按排列順序到達廚師手中,這樣廚師做菜就不會混亂,也不會遺忘。廚師將餐點與訂單一起轉交服務員,服務員檢查訂單并將所有東西帶到顧客的餐桌上。在此期間,顧客可以撤銷訂單或增刪訂單需求。
顧客不需要知道是誰來完成烹飪,廚師不需要知道是誰的訂單,紙質訂單用作命令,一直排在隊列中。這也就實現了請求者和接收者的解耦。
什么是命令模式
命令模式(Command Pattern)是一種行為設計模式,它把請求或操作封裝成一個包含有關請求所有信息的獨立對象,此轉換允許將請求作為方法參數傳遞,延遲或排隊請求的執行,并支持可撤消的操作,從而實現將請求者和接收者解耦。
優缺點
命令模式是一種靈活且功能強大的設計模式,主要優點是它允許在不修改現有客戶端代碼的情況下添加新的命令。此外,通過使用命令模式,可以將操作記錄到日志中、撤銷操作或者將操作進行隊列化等,同時他也有一些缺點。
優點
-
解耦性:命令模式通過將請求發送者與接收者解耦,使得請求發送者不需要知道接收者的具體實現細節,從而增強了系統的靈活性和可維護性。
-
可擴展性:通過添加新的具體命令類,可以很容易地擴展系統的功能,而不需要修改已有的代碼。
-
支持撤銷和重做:命令模式可以記錄請求的歷史操作,從而支持對操作的撤銷和重做,提供了更好的用戶體驗。
-
支持日志和隊列:可以將命令對象保存在日志中,實現系統的日志記錄功能。此外,命令對象還可以組織成隊列,實現命令的批處理和延遲執行。
-
命令模式符合“開-閉”原則。因為將具體命令封裝成了一個一個獨立的對象,所有當需要修改現有功能時,可以通過添加新代碼來實現,而不是修改已有的代碼。這樣可以提高代碼的可維護性和可擴展性,減少出錯率和代碼復雜度。具體點說,在增加新的具體命令或增加命令的接收者時,不需要修改原有調用者的代碼;而在增加新的調用者時,不需要修改原有的具體命令和接收者的代碼。
-
命令模式支持宏命令。
即將多個命令組合成一個命令。這樣可以將多個操作封裝成一個操作,減少了代碼的冗余和重復,提高代碼的復用率。
缺點
- 類的數量增加:引入命令模式會增加系統中的類的數量,特別是在有大量具體命令類的情況下,可能會導致類的數量激增,增加了系統的復雜性。
- 命令的單一性:每個具體命令類通常只封裝了一個特定的操作,這可能會導致系統中存在大量的具體命令類,增加了系統的管理和維護成本。
- 對象間的調用鏈可能過長:在命令模式中,請求發送者、命令對象、接收者之間可能存在多層的調用鏈,特別是在復雜的系統中,可能會導致調用鏈過長,影響系統的性能。
雖然命令模式有一些缺點,但在很多場景下仍然是一種非常有用的設計模式,特別是在需要支持撤銷、重做、日志記錄和隊列等功能的情況下。
使用命令模式的步驟
使用命令模式可以通過以下步驟進行:
- 確定參與者:首先,確定在系統中誰是命令的發起者(Invoker)、命令的接收者(Receiver)、以及具體的命令對象(Command)。
- 定義命令接口:創建一個命令接口,其中包含一個執行操作的方法(如execute())。這個接口可以是抽象類或者接口,具體取決于設計的需求。
- 實現具體命令類:針對每個具體的操作,創建一個具體的命令類,實現命令接口,并在其中封裝具體的操作實現。
- 創建接收者類:定義接收者類,實現命令所需的具體操作。 創建調用者類:創建一個調用者類,負責向具體的命令對象發送請求。
- 創建客戶端代碼:在客戶端代碼中創建具體的命令對象,并將其關聯到調用者對象上。
命令模式代碼示例
; 定義命令接口
class ICommand {Execute() {; 需要被覆蓋的方法(抽象方法)}
}; 定義具體命令A
class CommandA extends ICommand {Execute() {MsgBox("Command A Executed")}
}; 定義具體命令B
class CommandB extends ICommand {Execute() {MsgBox("Command B Executed")}
}; 定義調用者,負責執行命令
class Invoker {__New(command) {this.command := command}ExecuteCommand() {this.command.Execute()}
}; 客戶端代碼
main() {; 創建命令實例_commandA := CommandA()_commandB := CommandB(); 創建調用者并關聯命令_invokerA := Invoker(_commandA)_invokerB := Invoker(_commandB); 執行命令_invokerA.ExecuteCommand()_invokerB.ExecuteCommand()
}; 運行主程序
main()
合理使用AI工具自動生成代碼
上面的代碼是用Comate生成的
代碼就是上面那部分,我就不截圖了,稍微改改就可以運行。也可以把報錯信息提示給它,它會給出修改代碼示例。
還可以讓它輸出UML類圖:
這個mermaid代碼直接在CSDN的波紋MD編輯模式可以直接用哦。
感興趣可以在VSCODE中安裝這個AI編碼助手——Comate,感覺能在小眾語言AHK上表現這么好還是很令人驚訝的。