軟件設計模式:SDP04-02命令模式_第1頁
軟件設計模式:SDP04-02命令模式_第2頁
軟件設計模式:SDP04-02命令模式_第3頁
軟件設計模式:SDP04-02命令模式_第4頁
軟件設計模式:SDP04-02命令模式_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

命令模式命令模式模式動機與定義模式結構與分析模式實例與解析模式效果與應用模式擴展命令模式模式動機在現(xiàn)實生活中,通過開關可以控制一些電器的打開和關閉,例如電燈或者排氣扇。在購買開關時,我們并不知道它將來到底用于控制什么電器,也就是說,開關與電燈、排氣扇并無直接關系,一個開關在安裝之后可能用來控制電燈,也可能用來控制排氣扇或者其他電器設備。開關與電器之間通過電線建立連接,如果開關打開,則電線通電,電器工作;反之,開關關閉,電線斷電,電器停止工作。相同的開關可以通過不同的電線來控制不同的電器,如圖所示。命令模式模式動機命令模式模式動機我們可以將開關理解成一個請求的發(fā)送者,用戶通過它來發(fā)送一個“開燈”請求,而電燈是“開燈”請求的最終接收者和處理者,在圖中,開關和電燈之間并不存在直接耦合關系,它們通過電線連接在一起,使用不同的電線可以連接不同的請求接收者,只需更換一根電線,相同的發(fā)送者(開關)即可對應不同的接收者(電器)。命令模式模式動機在軟件開發(fā)中也存在很多與開關和電器類似的請求發(fā)送者和接收者對象,例如一個按鈕,它可能是一個“關閉窗口”請求的發(fā)送者,而按鈕點擊事件處理類則是該請求的接收者。此時,我們特別希望能夠以一種松耦合的方式來設計軟件,使得請求發(fā)送者與請求接收者能夠消除彼此之間的耦合,讓對象之間的調用關系更加靈活,可以靈活地指定請求接收者以及被請求的操作。命令模式為此類問題提供了一個較為完美的解決方案。命令模式模式動機命令模式可以將請求發(fā)送者和接收者完全解耦,發(fā)送者與接收者之間沒有直接引用關系,發(fā)送請求的對象只需要知道如何發(fā)送請求,而不必知道如何完成請求。命令模式模式定義命令模式(CommandPattern):將一個請求封裝為一個對象,從而讓我們可用不同的請求對客戶進行參數(shù)化;對請求排隊或者記錄請求日志,以及支持可撤銷的操作。命令模式是一種對象行為型模式,其別名為動作(Action)模式或事務(Transaction)模式。命令模式的定義比較復雜,提到了很多術語,例如“用不同的請求對客戶進行參數(shù)化”、“對請求排隊”,“記錄請求日志”、“支持可撤銷操作”等,在后面我們將對這些術語進行一一講解。命令模式模式定義命令模式的核心在于引入了命令類,通過命令類來降低發(fā)送者和接收者的耦合度,請求發(fā)送者只需指定一個命令對象,再通過命令對象來調用請求接收者的處理方法,其結構如圖所示:命令模式模式結構命令模式命令模式包含如下角色Command:抽象命令類一般是一個抽象類或接口,在其中聲明了用于執(zhí)行請求的execute()等方法,通過這些方法可以調用請求接收者的相關操作。ConcreteCommand:具體命令類是抽象命令類的子類,實現(xiàn)了在抽象命令類中聲明的方法,它對應具體的接收者對象,將接收者對象的動作綁定其中。在實現(xiàn)execute()方法時,將調用接收者對象的相關操作(Action)。命令模式命令模式包含如下角色Invoker:調用者,即請求發(fā)送者,它通過命令對象來執(zhí)行請求。一個調用者并不需要在設計時確定其接收者,因此它只與抽象命令類之間存在關聯(lián)關系。在程序運行時可以將一個具體命令對象注入其中,再調用具體命令對象的execute()方法,從而實現(xiàn)間接調用請求接收者的相關操作。Receiver:接收者執(zhí)行與請求相關的操作,它具體實現(xiàn)對請求的業(yè)務處理。命令模式模式分析命令模式的本質是對請求進行封裝,一個請求對應于一個命令,將發(fā)出請求的職責和執(zhí)行請求的職責分割開。每一個請求都對應一個操作:發(fā)送者發(fā)出請求,要求執(zhí)行一個操作;接收者收到請求,并執(zhí)行操作。命令模式允許請求者和接收者相互獨立,使得請求者不必知道接收者的接口,更不必知道請求是怎么被接收,以及操作是否被執(zhí)行、何時被執(zhí)行,以及是怎么被執(zhí)行的。命令模式模式分析命令模式使請求本身成為一個對象,這個對象和其他對象一樣可以被存儲和傳遞。命令模式的關鍵在于引入了抽象命令類,請求發(fā)送者針對抽象命令類編程,只有實現(xiàn)了抽象命令類的具體命令才與請求接收者相關聯(lián)。命令模式模式分析在最簡單的抽象命令類中只包含了一個抽象的execute()方法,其典型代碼如下所示:publicabstractclassCommand{ publicabstractvoidexecute();}命令模式模式分析具體命令類繼承了抽象命令類,它與請求接收者相關聯(lián),實現(xiàn)了在抽象命令類中聲明的execute()方法,并在實現(xiàn)時調用接收者的請求響應方法action(),不同的具體命令類提供了execute()方法的不同實現(xiàn),并調用不同接收者的請求處理方法。其典型代碼如下所示:publicclassConcreteCommandextendsCommand{ privateReceiverreceiver;//維持一個對請求接收者對象的引用 publicvoidexecute() {

receiver.action();//調用請求接收者的業(yè)務處理方法 }}命令模式模式分析對于請求發(fā)送者即調用者而言,將針對抽象命令類進行編程,可以通過構造注入或者設值注入的方式在運行時傳入具體命令類對象,并在業(yè)務方法中調用命令對象的execute()方法,其典型代碼如下所示:publicclassInvoker{ privateCommandcommand;//維持一個對命令對象的引用 publicInvoker(Commandcommand)//構造注入 {mand=command;} publicvoidsetCommand(Commandcommand)//設值注入 {mand=command;}

publicvoidcall()//業(yè)務方法,用于調用命令類的方法 {command.execute();}}命令模式模式分析請求接收者Receiver類具體實現(xiàn)對請求的業(yè)務處理,它提供了action()方法,用于執(zhí)行與請求相關的操作,其典型代碼如下所示:publicclassReceiver{ publicvoidaction() { //具體操作

}}命令模式模式分析命令模式順序圖:命令模式模式擴展-命令隊列有時候一個請求發(fā)送者不止發(fā)送一個請求,將不止一個請求接收者產(chǎn)生響應,我們需要將多個請求排隊,當發(fā)送請求時,這些請求接收者將逐個執(zhí)行業(yè)務方法,完成對請求的處理。此時,我們可以通過命令隊列來實現(xiàn)。命令隊列的實現(xiàn)方法有多種形式,其中最常用、靈活性最好的一種方式是增加一個CommandQueue類,由該類來負責存儲多個命令對象,而不同的命令對象可以對應不同的請求接收者。命令模式模式擴展-命令隊列CommandQueue類的典型代碼如下所示:classCommandQueue{//定義一個ArrayList來存儲命令隊列

privateArrayList<Command>commands=newArrayList<Command>();publicvoidaddCommand(Commandcommand){commands.add(command);}publicvoidremoveCommand(Commandcommand){commands.remove(command);}//循環(huán)調用每一個命令對象的execute()方法

publicvoidexecute(){for(Objectcommand:commands){((Command)command).execute();}}}命令模式模式擴展-命令隊列在增加了命令隊列類CommandQueue以后,請求發(fā)送者類Invoker將針對CommandQueue編程,代碼修改如下:classInvoker{privateCommandQueue

commandQueue;//維持一個CommandQueue對象的引用

//構造注入publicInvoker(CommandQueue

commandQueue){mandQueue=commandQueue;}//設值注入

publicvoidsetCommandQueue(CommandQueue

commandQueue){

mandQueue=commandQueue;}//調用CommandQueue類的execute()方法

publicvoidcall(){commandQueue.execute();}}命令模式模式擴展-命令隊列命令隊列與我們常說的“批處理”有點類似。批處理,顧名思義,可以對一組對象(命令)進行批量處理,當一個發(fā)送者發(fā)送請求后,將有一系列接收者對請求作出響應,命令隊列可以用于設計批處理應用程序,如果請求接收者的接收次序沒有嚴格的先后次序,我們還可以使用多線程技術來并發(fā)調用命令對象的execute()方法,從而提高程序的執(zhí)行效率。命令模式模式擴展-請求日志請求日志就是將請求的歷史記錄保存下來,通常以日志文件(LogFile)的形式永久存儲在計算機中。很多系統(tǒng)都提供了日志文件,例如Windows日志文件、Oracle日志文件等,日志文件可以記錄用戶對系統(tǒng)的一些操作(例如對數(shù)據(jù)的更改)。請求日志文件可以實現(xiàn)很多功能,常用功能如下:一旦系統(tǒng)發(fā)生故障,日志文件可以為系統(tǒng)提供一種恢復機制,在請求日志文件中可以記錄用戶對系統(tǒng)的每一步操作,從而讓系統(tǒng)能夠順利恢復到某一個特定的狀態(tài);命令模式模式擴展-請求日志請求日志也可以用于實現(xiàn)批處理,在一個請求日志文件中可以存儲一系列命令對象,例如一個命令隊列;可以將命令隊列中的所有命令對象都存儲在一個日志文件中,每執(zhí)行一個命令則從日志文件中刪除一個對應的命令對象,防止因為斷電或者系統(tǒng)重啟等原因造成請求丟失,而且可以避免重新發(fā)送全部請求時造成某些命令的重復執(zhí)行,只需讀取請求日志文件,再繼續(xù)執(zhí)行文件中剩余的命令即可。命令模式模式擴展-請求日志實例:通過一個可視化界面對配置文件進行增刪改等操作,同時,將對配置文件的操作請求記錄在日志文件中,如果重新創(chuàng)建配置文件,只需要執(zhí)行保存在日志文件中的命令對象即可修改配置文件。使用命令模式進行設計。命令模式模式擴展-請求日志命令模式模式擴展-請求日志請求日志的實現(xiàn)參考代碼(RequestLog)演示……命令模式模式擴展-撤銷操作在命令模式中,可以通過調用一個命令對象的execute()方法來實現(xiàn)對請求的處理,如果需要撤銷(Undo)請求,可通過在命令類中增加一個逆向操作來實現(xiàn)。除了通過一個逆向操作來實現(xiàn)撤銷(Undo)外,還可以通過保存對象的歷史狀態(tài)來實現(xiàn)撤銷,后者可使用備忘錄模式(MementoPattern)來實現(xiàn)。實例:開發(fā)一個簡易計算器,該計算器可以實現(xiàn)簡單的數(shù)學運算,還可以對運算實施撤銷操作。命令模式模式擴展-撤銷操作撤銷操作的實現(xiàn)

命令模式模式擴展-撤銷操作撤銷操作的實現(xiàn)參考代碼(UndoDemo)演示……命令模式模式擴展-宏命令宏命令又稱為組合命令,它是命令模式和組合模式聯(lián)用的產(chǎn)物。宏命令是一個具體命令類,它擁有一個集合屬性,在該集合中包含了對其他命令對象的引用。通常宏命令不直接與請求接收者交互,而是通過它的成員來調用接收者的方法。當調用宏命令的execute()方法時,將遞歸調用它所包含的每個成員命令的execute()方法,一個宏命令的成員可以是簡單命令,還可以繼續(xù)是宏命令。執(zhí)行一個宏命令將觸發(fā)多個具體命令的執(zhí)行,從而實現(xiàn)對命令的批處理。命令模式模式擴展宏命令命令模式命令模式實例與解析實例一:電視機遙控器電視機是請求的接收者,遙控器是請求的發(fā)送者,遙控器上有一些按鈕,不同的按鈕對應電視機的不同操作。抽象命令角色由一個命令接口來扮演,有三個具體的命令類實現(xiàn)了抽象命令接口,這三個具體命令類分別代表三種操作:打開電視機、關閉電視機和切換頻道。顯然,電視機遙控器就是一個典型的命令模式應用實例。命令模式命令模式實例與解析實例一:電視機遙控器命令模式命令模式實例與解析實例一:電視機遙控器參考代碼(sample01)演示……命令模式命令模式實例與解析實例二:功能鍵設置為了用戶使用方便,某系統(tǒng)提供了一系列功能鍵,用戶可以自定義功能鍵的功能,如功能鍵FunctionButton可以用于退出系統(tǒng)(SystemExitClass),也可以用于打開幫助界面(DisplayHelpClass)。用戶可以通過修改配置文件來改變功能鍵的用途,現(xiàn)使用命令模式來設計該系統(tǒng),使得功能鍵類與功能類之間解耦,相同的功能鍵可以對應不同的功能。命令模式命令模式實例與解析實例二:功能鍵設置命令模式模式優(yōu)點降低系統(tǒng)的耦合度。由于請求者與接收者之間不存在直接引用,因此請求者與接收者之間實現(xiàn)完全解耦,相同的請求者可以對應不同的接收者,同樣,相同的接收者也可以供不同的請求者使用,兩者之間具有良好的獨立性。新的命令可以很容易地加入到系統(tǒng)中。由于增加新的具體命令類不會影響到其他類,因此增加新的具體命令類很容易,無須修改原有系統(tǒng)源代碼,甚至客戶類代碼,滿足“開閉原則”的要求。命令模式模式優(yōu)點為請求的撤銷(Undo)和恢復(Redo)操作提供了一種設計和實現(xiàn)方案??梢员容^容易地設計一個命令隊列或宏命令(組合命令)。命令模式模式缺點使用命令模式可能會導致某些系統(tǒng)有過多的具體命令類。因為針對每一個對請求接收者的調用操作都需要設計一個具體命令類,因此在某些系統(tǒng)中可能需要提供大量的具體命令類,這將影響命令模式的使用。命令模式模式適用環(huán)境系統(tǒng)需要將請求調用者和請求接收者解耦,使得調用者和接收者不直接交互。請求調用者無須知道接收者的存在,也無須知道接收者是誰,接收者也無須關心何時被調用。系統(tǒng)需要在不同的時間指定請求、將請求排隊和執(zhí)行請求。一個命令對象和請求的初始調用者可以有不同的生命期,換言之,最初的請求發(fā)出者可能已經(jīng)不在了,而命令對象本身仍然是活動的,可以通過該命令對象去調用請求接收者,而無須關心請求調用者的存在性,可以通過請求日志文件等機制來具體實現(xiàn)。命令模式模式適用環(huán)境系統(tǒng)需要支持命令的撤銷(Undo)操作和恢復(Redo)操作。系統(tǒng)需要將一組操作組合在一起形成宏命令。命令模式模式應用(1)Java語言使用命令模式實現(xiàn)AWT/SwingGUI的委派事件模型(DelegationEventModel,DEM)。在AWT/Swing中,F(xiàn)rame、Button等界面組件是請求發(fā)送者,而AWT提供的事件監(jiān)聽器接口和事件適配器類是抽象命令接口,用戶可以自己寫抽象命令接口的子類來實現(xiàn)事件處理,即實

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論