命令模式

實例場景:java

一、餐館點菜吃飯:當咱們在餐館進行點菜的時候,通常咱們會進行點菜,而後服務員下訂單,而後廚師根據訂單進行炒菜,最後擺在咱們面前的就是一盤美味佳餚了。程序員

二、領導下命令:領導要員工作事的時候,通常是把事情告訴祕書或行政人員,而後由她們把領導安排的事情下發到員工。設計模式

三、當咱們想要聽音樂,只要咱們按下播放鍵盤,相應的音樂就自動播放了。架構

以上場景中咱們都使用了一種設計模式:命令模式框架

命令模式把一個請求或者操做封裝到一個對象中。命令模式運行系統使用不一樣的請求把客戶端參數化,對請求排隊或者記錄請求日誌,能夠提供命令的撤銷和恢復功能。ide

命令模式中是把一個命令封裝爲一個對象。
測試

命令模式的角色ui

客戶角色:建立一個具體命令對象,並肯定其接受者this

命令角色:聲明一個給全部具體命令類的抽象接口,這是一個抽象角色,一般由一個接口或抽象類實現。spa

具體命令角色:定義接收者和行爲之間的弱耦合,實現execute方法,負責調用接收者的相應操做。

請求者角色:負責調用命令對象執行請求。

接收者角色:負責具體實施和執行一個請求。

在上面的實例場景中,場景分析以下:

一、餐館點菜,咱們至關與一個客戶角色,咱們點菜就是發送命令,不一樣的人或有不一樣的命令請求,就應該把命令設計爲抽象類,用戶發出的請求就是具體的命令,服務員就是一個請求者,她把命令也就是客戶的訂單給接受者廚師,廚師只要照着菜單作菜,作好後給客戶便可,客戶不用去管菜是怎樣作出來的,只要發送一個命令,而後獲得本身的結果就能夠了。

二、領導下命令:我是老總,我只管發個命令,至於這個命令發給誰,誰執行,關我P事,我發錢請人不是爲了給本身找麻煩。你是負責事情的員工,你的天職是作好上級交給你的任務,踏踏實實,不要知道太多,不要八卦,不要問太多了。Client對象是發佈命令的。Invoker對象是傳遞命令的,就是跑腿的。Receiver是受氣包,底層最累的程序員,負責幹活吧

三、一個Mp3。你按了一個播放鍵盤,就播放了。這就能夠算是命令模式的一種。 你是Client ,按鍵是Invoker,mp3是Receiver,播放就是一個命令Command對象。

命令模式的好處

◆很容易構造一個命令隊列

◆記錄相關的命令日誌

◆增長命令的狀態,實現命令的撤銷和重作

◆容許接受請求的一方決定是否可作

◆新的命令垂手可得能夠加入其中

缺點可能會有過多的具體命令類存在

場景代碼實現:

package cn.com.command; //聲明一個命令角色 public interface Command { 	public void execute(); } 

package cn.com.command; //定義一個接收者,至關與一個廚師 //負責具體實施和執行一個請求 public class Recevier { 	public void doAction(){ 		System.out.println("客戶發訂單了,我要炒菜了"); 	} } 

package cn.com.command; //具體的命令角色,負責調用接收者相應的操做 public class ConcreteCommand implements Command{ 	private Recevier recevier; 	public ConcreteCommand(Recevier recevier){ 		this.recevier=recevier; 	} 	 	@Override 	public void execute() { 		recevier.doAction(); 	} } 
package cn.com.command; //定義一個請求者角色, //負責調用命令對象,執行請求 public class Invoker { 	private Command command; 	public Invoker(Command command){ 		this.command=command; 	} 	 	public void doInvokerAction(){ 		command.execute(); 	} } 

package cn.com.command; //建立客戶角色,客戶進行點菜 public class Client { 	public static void main(String[] args) { 		//生成一個具體的廚師角色 		Recevier recevier=new Recevier(); 		//生成一個菜單命令對象 		Command command=new ConcreteCommand(recevier); 		//服務員把菜單給廚師,廚師具體實施,進行炒菜 		Invoker invoker=new Invoker(command); 		invoker.doInvokerAction(); 		//在整個應用場景中,其實是請求者調用具體命令對象,具體命令對象調用接收者 	} } 

代碼輸出:
客戶發訂單了,我要炒菜了
//在整個應用場景中,其實是請求者調用具體命令對象,具體命令對象調用接收者
JUnit框架中,運用了咱們的命令模式:

用戶編寫測試用例TestCase,把這些測試用例組成請求(多是一個或者多個),發送到JUnit,而後由JUnit執行,最後報告詳細測試結果包括執行的時間,錯誤方法,錯誤位置等。這樣測試用例的開發人員就不須要知道請求TestCase的具體操做信息,僅把它看成一種命令來執行,而後把執行測試結果發給測試人員。這樣就使JUnit框架和TestCase的開發人員獨立開來,使得請求的一方沒必要知道接收請求一方的詳細信息,更沒必要知道是怎樣被接收,以及怎樣被執行的,實現系統的鬆藕合。

使用命令模式後給JUnit系統的架構帶來的效果

a、將實現請求的一方(TestCase開發)和調用一方JUnit進行解耦

b、使新的TestCase很容易加入,無需改變已有的類,只需繼承TestCase類便可,這樣方便了測試人員

c、能夠將多個TestCase進行組合成一個複合命令,TestSuit就是它的複合命令,使用了組合模式

d、容易把請求的TestCase組成請求隊列,這樣使接收請求的一方JUnit框架,容易決定是否執行請求,一旦發現測試用例失敗或者錯誤能夠當即中止進行報告

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息