軟體設計模式學習(十八)命令模式
阿新 • • 發佈:2020-05-18
> 命令模式將請求傳送者與請求接收者解耦,在傳送者與接收者之間引入命令物件,將傳送者的請求封裝在命令物件中,請求傳送者通過命令物件來間接引用接收者,使得系統具有更好的靈活性,使用者可以根據需要為請求傳送者增加新的命令物件而無須修改原有系統
## 模式動機 舉個現實生活中的例子,開關是請求的傳送者,電燈是請求的接收者,它們之間不存在直接的耦合關係,而是通過電線連線到一起,開關不需要知道如何將開燈或關燈請求傳輸給電燈,而是通過電線來完成這項功能。 此時可以理解為電線充當封裝請求的命令物件,開關如果開則電線通電,並呼叫電燈的開燈方法,反之則關燈。不同電線可以連線不同的請求接收者,因此只需更換一根電線,相同的開關即可操作不同的電器裝置。 在軟體設計中,我們也像上述例子一樣,經常需要向某些物件傳送請求,但是不知道請求接收者是誰,也不知道被請求的操作是哪個,我們只需指定具體的請求接收者即可,此時,可以使用命令模式使請求傳送者與請求接收者消除彼此之間的耦合,讓物件之間的呼叫更加啊靈活。
## 模式結構 ![](https://img2020.cnblogs.com/blog/1759254/202005/1759254-20200518170459082-815559773.png) 1. Command(抽象命令類) 一般是介面,其中聲明瞭用於執行請求的 execute() 等方法,通過這些方法呼叫請求接收者的相關操作 2. ConcreteCommand(具體命令類) 是抽象命令類的子類,實現在抽象命令類中宣告的方法。它對應具體接收者物件,繫結接收者物件的動作。在實現 execute() 方法時將呼叫接收者物件的相關操作(Action) 3. Invoker(呼叫者) 即請求的傳送者,又稱請求者,通過命令物件來執行請求。一個呼叫者並不需要再設計時確定其接收者,因此它與抽象命令類之間只存在關聯關係。程式執行時呼叫具體命令物件的 execute() 方法,間接呼叫接收者的相關操作 4. Receiver(接收者) 執行者執行與請求相關的操作,它具體實現對請求的業務處理 5. Client(客戶類) 客戶類中需建立呼叫者物件和具體命令物件,再建立具體命令物件時指定其對應接收者,傳送者和接收者之間無直接關係,透過具體命令物件實現間接呼叫
## 模式優缺點 命令模式優點: 1. 降低系統耦合度 2. 新的命令可以很容易地加入系統中 3. 可以比較容易地設計一個設計一個命令佇列和巨集命令(組合命令) 4. 可以方便實現對請求的 Undo 和 Redo 命令模式缺點: 1. 使用命令模式可能導致某些系統有過多的具體命令類
## 撤銷操作的實現 我們可以通過對命令類進行修改使得系統支援撤銷操作和恢復操作,,抽象命令類(AbstractCommand)宣告一個 undo() 方法 ```java public interface AbstractCommand { public void undo(); public void execute(); } ``` 具體命令類(ConcreteCommand)實現在抽象命令類(AbstractCommand)中宣告的 execute() 和 undo() 方法 ```java public class ConcreteCommand implements AbstractCommand { private Receiver receiver; public ConcreteCommand() { receiver = new Receiver(); } @Override public void execute() { receiver.method; } @Override public void undo() { // 撤銷 execute() 操作 } } ``` 呼叫者(Invoker)照常引用一個抽象命令 AbstractCommand 型別的物件 command,通過該 command 物件間接呼叫接收者 Receiver 類的業務方法 ```java public class Invoker { private AbstractCommand command; public Invoker(AbstractCommand command) { this.openCommand = openCommand; } public void method() { command.execute(); } public void undo() { // 撤銷操作 } } ``` 上述例項只能實現一步撤銷操作,因為沒有儲存命令物件的歷史狀態,可以通過引入一個命令集合或其他方式來儲存中間狀態,從而實現多次撤銷操作
## 巨集命令 巨集命令又稱組合命令,它是命令模式和組合模式聯用的產物。巨集命令也是一個具體命令,不過它包含了對其他命令物件的引用,在呼叫巨集命令的 execute() 方法,將遞迴呼叫它所包含的每個成員命令的 execute() 方法。一個巨集命令的成員物件可以是簡單命令,也可以繼續是巨集命令。 ![](https://img2020.cnblogs.com/blog/1759254/202005/1759254-20200518170650559-91425877.png)
[上一站:軟體設計模式學習(十七)職責鏈模式](https://www.cnblogs.com/Yee-Q/p/12901361.html