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

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

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

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

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

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

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

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

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

//構(gòu)造注入publicInvoker(CommandQueue

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

publicvoidsetCommandQueue(CommandQueue

commandQueue){

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

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

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

溫馨提示

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

評論

0/150

提交評論