天天看點

設計模式:指令模式(Command)

 将一個請求封裝為一個對象,進而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以支援可撤銷的操作。

設計模式:指令模式(Command)

指令模式的角色

1. 用戶端角色(Client):建立一個具體指令(ConcreteCommand)對象并确定其接收者。

2. 指令角色(Command):聲明一個給所有指令類的抽象接口。

3. 具體指令角色(ConcreteCommand):定義一個接收者和行為之間的弱耦合;實作execute()方法,負責調用接收者的相應操作。execute()方法叫做執行方法。

4. 請求者角色(Invoker):負責調用指令對象執行請求,相關的方法叫做行動方法。

5. 接收者角色(Receiver):負責具體實施和執行一個請求。任何一個類都可以稱為接收者,實施和執行請求的方法叫做行動方法。

舉個簡單例子(錄音機有播音Play,倒帶Rewind和停止Stop功能)

1 接收者角色

2 抽象指令角色

3 具體指令角色

4 請求這角色(由按鍵扮演)

5 用戶端角色

輸出:

 所謂的宏指令簡單點說就是包含多個指令的指令,是一個指令的組合。

 修改上面的案例,當用戶端需要一個記錄的工,可以把一個一個指令記錄下來,再在任何需要的時候重新把這些記錄下來的指令一次執行,這就是所謂的宏指令功能。

1 系統需要一個代表宏指令的接口,以定義出具體宏指令所需要的接口

2 具體的宏指令MarcoAudioCommand類負責把個别的指令合成宏指令

3 用戶端

适用場景

 在下面的情況下應當考慮應用指令模式:

使用指令模式作為CallBack在面向對象系統中的替代。CallBack講的便是先将一個函數等級上,然後在以後調用此函數。

需要在不同的時間指定請求、将請求排隊。一個指令對象和原先的請求發出者可以有不同的生命期。換言之,原先的請求發出者可能已經不存在了,而名對象本身仍然是活動的。這時指令的接受者可以是在本地,也可以在網絡的另外一個位址。指令對象可以在串行化之後送到一台機器上去。

系統需要支援指令的撤銷(undo)。指令對象可以把狀态存儲起來,等到用戶端需要撤銷指令所産生的效果時,可以調用undo()方法,把指令所産生的效果撤銷掉。指令對象還可以提供redo()方法,以供用戶端在需要時,再重新實施指令效果。

日志請求(系統恢複):如果一個系統要将系統中所有的資料更新到日志裡,以便在系統崩潰時,可以根據日志裡讀回所有的資料更新指令,重新調用Execute()方法一條一條執行這些指令,進而恢複系統在崩潰前所做的資料更新。

工作隊列,線程池,日程安排。

優缺點

優點:

更松散的耦合:指令模式使得發起指令的對象(用戶端)和具體實作指令的對象(接收者)完全解耦,也就是說發起指令的對象完全不知道具體實作對象是誰,也不知道該如何實作。

更動态的控制:指令模式把請求封裝起來,可以動态地對它進行參數化、隊列化和日志化,進而使得系統更靈活。

很自然的複合指令:指令模式中的指令對象能夠很容易地組合成複合指令,也就是宏指令,進而使系統操作更簡單,功能更強大。

更好的擴充性:由于發起指令的對象和具體的實作完全解耦,是以擴充新的指令就很容易,隻需要實作新的指令對象,然後在裝配的時候,把具體的實作對象設定到指令對象中,然後就可以使得這個指令對象,已有的實作完全不用變化。

缺點:

使用指令模式可能會導緻某些系統有過多的具體指令類。因為針對每一個指令都需要設計一個具體指令類,是以某些系統可能需要大量具體指令類,這将影響指令模式的使用。

JDK中的指令模式 java.lang.Runnable javax.swing.Action

參考資料