中間件技術(shù)應用課件第一部分-設(shè)計模式簡介_第1頁
中間件技術(shù)應用課件第一部分-設(shè)計模式簡介_第2頁
中間件技術(shù)應用課件第一部分-設(shè)計模式簡介_第3頁
中間件技術(shù)應用課件第一部分-設(shè)計模式簡介_第4頁
中間件技術(shù)應用課件第一部分-設(shè)計模式簡介_第5頁
已閱讀5頁,還剩201頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第一部分設(shè)計模式簡介

一、什么是設(shè)計模式1.設(shè)計模式“設(shè)計模式(pattern)是從許多優(yōu)秀的軟件系統(tǒng)中總結(jié)出的成功的可復用的設(shè)計方案”。2.GOF之說“盡管Alexander所指的是城市和建筑設(shè)計模式,但他的思想也同樣適用于面向?qū)ο笤O(shè)計模式,只是在面向?qū)ο蟮慕鉀Q方案里,我們用對象和接口代替了墻壁和門窗。兩類模式的核心都在于提供了相關(guān)問題的解決方案”。第一部分設(shè)計模式簡介

一、什么是設(shè)計模式1模式的四個基本要素1.名稱一個模式的名稱高度概括該模式的本質(zhì),有利于該行業(yè)統(tǒng)一術(shù)語、便于交流使用。2.問題描述應該在何時使用模式,解釋設(shè)計問題和問題存在的前因后果,描述在怎樣的環(huán)境下使用該模式。3.方案描述設(shè)計的組成部分,它們之間的相互關(guān)系及各自的職責和協(xié)作方式。4.效果描述模式的應用效果及使用模式應當權(quán)衡的問題。主要效果包括使用模式對系統(tǒng)的靈活性、擴充性和復用性的影響。模式的四個基本要素2模式的四個基本要素例如,GOF之書如下記錄中介者模式:名稱中介者問題用一個中介者來封裝一系列的對象交互。中介者使各對象不需要顯示地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。方案中介者(Mediator)接口、具體中介者(ConcreteMediator)、同事(Colleague)、具體同事(ConcreteColleague)。效果減少了子類的生成、將各個同事解耦、簡化了對象協(xié)議、控制集中化。模式的四個基本要素例如,GOF之書如下記錄中介者模式:3二、設(shè)計模式的起源軟件領(lǐng)域的設(shè)計模式起源主要是受到1977年建筑大師Alexander出版的《APatternLanguage:Towns,Building,Construction》一書。Alexander在其著作中將其建筑行業(yè)中的許多問題的最佳解決方案記錄為200多種模式,其思想不僅在建筑行業(yè)影響深遠,而且很快影響到了軟件設(shè)計領(lǐng)域。二、設(shè)計模式的起源軟件領(lǐng)域的設(shè)計模式起源主要是受到19741987年,KentBeck和WardCunningham將Alexander在建筑學上的模式觀點應用于軟件設(shè)計,開發(fā)了一系列模式,并用Smalltalk語言實現(xiàn)了雅致的用戶界面。KentBeck和WardCunningham在1987年舉行的一次面向?qū)ο蟮臅h上發(fā)表了論文:《在面向?qū)ο缶幊讨惺褂媚J健?,該論文發(fā)表后,有關(guān)軟件的設(shè)計模式論文以及著作相繼出版。1設(shè)計模式的起源1987年,KentBeck和WardC52GOF之著作1.目前,被公認在設(shè)計模式領(lǐng)域最具影響力的著作是ErichGamma、RichardHelm、RalphJohnson和JohnVlissides在1994年合作出版的著作:《DesignPatterns:ElementsofReusableObject-OrientedSoftware》(中譯本《設(shè)計模式:可復用的面向?qū)ο筌浖幕驹怼贰?.該書的四位作者在其著作中記錄了他們在四年多的工作中所發(fā)現(xiàn)的23個模式。3.《設(shè)計模式》一書被廣大喜愛者昵稱為GOF(GangofFour)之書,被認為是學習設(shè)計模式的必讀著作。被公認為是設(shè)計模式領(lǐng)域的奠基之作。2GOF之著作1.目前,被公認在設(shè)計模式領(lǐng)域最具影響力的著63學習設(shè)計模式的重要性1.一個好的設(shè)計系統(tǒng)往往是易維護、易擴展、易復用的。2.有經(jīng)驗的設(shè)計人員或團隊知道如何使用面向?qū)ο笳Z言編寫出易維護、易擴展和易復用的程序代碼。3.《設(shè)計模式》一書正是從這些優(yōu)秀的設(shè)計系統(tǒng)中總結(jié)出的設(shè)計精髓。4.學習設(shè)計模式對提高設(shè)計能力無疑是非常有幫助的,盡管GOF之書并沒有收集全部的模式,但所闡述的23種模式無疑是使用頻率最高的模式。5.設(shè)計模式的目的不是針對軟件設(shè)計和開發(fā)中的每個問題都給出解決方案,而是針對某種特定環(huán)境中通常都會遇到的某種軟件開發(fā)問題給出的可重用的一些解決方案。3學習設(shè)計模式的重要性1.一個好的設(shè)計系統(tǒng)往往是易維護、易76.學習設(shè)計模式不僅可以使我們使用好這些成功的模式,更重要的是可以使我們更加深刻地理解面向?qū)ο蟮脑O(shè)計思想,非常有利于我們更好地使用面向?qū)ο笳Z言解決設(shè)計中的問題。7.學習設(shè)計模式對于進一步學習、理解和掌握框架是非常有幫助的,比如JavaEE中就大量使用了《設(shè)計模式》一書中的模式,對于熟悉設(shè)計模式的開發(fā)人員,很容易理解這些框架的結(jié)構(gòu),繼而很好地使用框架來設(shè)計他們的系統(tǒng)。學習設(shè)計模式的重要性6.學習設(shè)計模式不僅可以使我們使用好這些成功的模式,更重要的88.《設(shè)計模式》一書所總結(jié)的成功模式不僅適合于面向?qū)ο笳Z言,其思想及解決問題的方式也適合于任何和設(shè)計相關(guān)的行業(yè),因此學習掌握設(shè)計模式無疑是非常有益的。學習設(shè)計模式的重要性8.《設(shè)計模式》一書所總結(jié)的成功模式不僅適合于面向?qū)ο笳Z言,9合理使用模式不是軟件的任何部分都需要套用模式來設(shè)計的,必須針對具體問題合理的使用模式。1.正確使用當你設(shè)計某個系統(tǒng),并確認所遇到的問題剛好適合使用某個模式,就可以考慮使用該模式到你的系統(tǒng)設(shè)計中,畢竟該模式已經(jīng)被公認是解決該問題的成功方案,能使設(shè)計的系統(tǒng)易維護、可擴展性強、復用性好,而且這些經(jīng)典的模式也容易讓其他開發(fā)人員了解你的系統(tǒng)和設(shè)計思想。2.避免教條模式不是數(shù)學公式、也不是物理定律、更不是軟件設(shè)計中的“法律”條文,你完全可以修改模式中的部分結(jié)構(gòu)以符合你的設(shè)計要求。

合理使用模式不是軟件的任何部分都需要套用模式來設(shè)計的103.模式挖掘模式不是用理論推導出來的,而是從真實世界的軟件系統(tǒng)中被發(fā)現(xiàn)、按著一定規(guī)范總結(jié)出來的可以被復用的方案。許多文獻或書籍里闡述的眾多模式實際上都是GOF書中經(jīng)典模式的變形,這些變形模式都經(jīng)過所謂的“三次規(guī)則”,即該模式已經(jīng)在真實世界的三個方案中被成功的采用。可以從某個系統(tǒng)中洞察出某種新模式,只要經(jīng)過“三次規(guī)則”就會被行業(yè)認可。4.避免亂用不是所有的設(shè)計中都需要使用模式,因為模式不是發(fā)明出來的,而是總結(jié)出來的,事實上,真實世界中的許多設(shè)計實例都沒有使用過GOF之書中的經(jīng)典模式。在進行設(shè)計時,盡可能用最簡單的方式滿足系統(tǒng)的要求,而不是費盡心機地琢磨如何在這個問題中使用模式.合理使用模式3.模式挖掘合理使用模式115.了解反模式所謂反模式就是從某些軟件系統(tǒng)中總結(jié)出的不好的設(shè)計方案,反模式就是告訴你如何采用一個不好的方案解決一個問題。既然是一個不好的方案,為何還有可能被重復使用呢?這是因為,這些不好的方案表面上往往有很強的吸引力,人們很難一眼就發(fā)現(xiàn)它的弊端,因此,發(fā)現(xiàn)一個反模式也是非常有意義的工作。在有了一定的設(shè)計模式的基礎(chǔ)之后,你可以用搜索引擎查找有關(guān)反模式的信息,這對于學習好設(shè)計模式也是非常有幫助的。合理使用模式5.了解反模式合理使用模式12一個設(shè)計中,可能并不需要使用模式就可以很好地滿足系統(tǒng)的要求,如果牽強地使用某個模式可能會在系統(tǒng)中增加許多額外的類和對象,影響系統(tǒng)的性能,因為大部分設(shè)計模式往往會在系統(tǒng)中加入更多的層,這不但增加復雜性,而且系統(tǒng)的效率也會下降。合理使用模式一個設(shè)計中,可能并不需要使用模式就可以13什么是框架框架不是模式,框架是針對某個領(lǐng)域,提供用于開發(fā)應用系統(tǒng)的類的集合,程序設(shè)計者可以使用框架提供的類設(shè)計一個應用程序,而且在設(shè)計應用程序時可以針對特定的問題使用某個模式。1.層次不同模式比框架更抽象,模式是在某種特定環(huán)境中,針對一個軟件設(shè)計出現(xiàn)的問題而給出的可復用的解決方案,不能向使用者提供可以直接使用的類,設(shè)計模式只有在被設(shè)計人員使用時才能表示為代碼,什么是框架框架不是模式,框架是針對某個領(lǐng)域,提供用于14例如,GOF描述的中介者模式:“用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯示地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互”,該模式在解決方案中并沒有提供任何類的代碼,只是說明設(shè)計者可以針對特定的問題使用該模式給出的方案??蚣芎湍J讲煌皇且环N可復用的設(shè)計方案,它是由可用于設(shè)計解決某個問題的一些類組成的集合,程序設(shè)計人員通過使用框架提供的類或擴展框架提供的類進行應用程序的設(shè)計,例如。在Java中,開發(fā)人員使用Swing框架提供的類設(shè)計用戶界面;使用Set(集合)框架提供的類處理數(shù)據(jù)結(jié)構(gòu)相關(guān)的算法等。什么是框架例如,GOF描述的中介者模式:“用一個中介對象152.范圍不同模式本質(zhì)上是邏輯概念,以概念的形式而存在,模式所描述的方案獨立于編程語言。Java程序員、C++程序員或SmallTalk程序員都可以在自己的系統(tǒng)設(shè)計中使用某個模式??蚣艿膽玫姆秶呛芫唧w的,它們不是以概念的形式而存在,而是以具體的軟件組織而存在,只能被特定的軟件設(shè)計者使用,比如Java提供的Swing框架只能為Java應用程序所使用。什么是框架2.范圍不同什么是框架163.相互關(guān)系一個框架往往會包括多個設(shè)計模式,它們是面向?qū)ο笙到y(tǒng)獲得最大復用的方式,較大的面向?qū)ο髴脮啥鄬颖舜撕献鞯目蚣芙M成,例如,JavaWeb設(shè)計中的Struts,Spring和Hibernate等框架??蚣茏兊迷絹碓狡毡楹椭匾?,導致許多開源框架的出現(xiàn),而且一個著名的框架往往是許多設(shè)計模式的具體體現(xiàn),我們甚至可以在一些成功的框架中挖掘出新的模式。什么是框架3.相互關(guān)系什么是框架17使用Java描述模式的必要性

Java不僅可以用來開發(fā)大型的桌面應用程序,而且特別適合于Internet的應用開發(fā)。目前,Java語言不僅是一門正在被廣泛使用的編程語言,而且已成為軟件設(shè)計開發(fā)者應當掌握的一門基礎(chǔ)語言。GOF之書無疑是經(jīng)典之作,但是該書中的示例代碼相當簡練,而且是采用C++描述的,另外C++中提到的接口就是指類的方法,但是在Java中,類和接口是兩個不同的概念。所以采用Java語言講解GOF之書中的23個模式,其原因不僅是因為Java語言的廣泛使用,而且希望設(shè)計模式的學習更加適合具有一定Java語言基礎(chǔ)的學生和程序員。使用Java描述模式的必要性

Java不僅可以18第二部分,UML類圖簡介Student+name:String#age:int-money:double+setName(String):void#printMess():void+getAge():intsetAge(int):void-getMoney();類(Class)第二部分,UML類圖簡介Student+name:Stri19<<interface>>Creator+MAX:int+factoryMethod():Product2.接口(Interface)<<interface>>+MAX:int+factoryM203.泛化關(guān)系(繼承關(guān)系,Generalization)3.泛化關(guān)系(繼承關(guān)系,Generalization)214.關(guān)聯(lián)關(guān)系(Association)4.關(guān)聯(lián)關(guān)系(Association)225.依賴關(guān)系(Dependency)5.依賴關(guān)系(Dependency)236.實現(xiàn)關(guān)系(Realization)6.實現(xiàn)關(guān)系(Realization)24第三部分面向?qū)ο蟮膸讉€基本原則

3.1面向抽象原則1.抽象類和接口(1)抽象(abstract)類抽象(abstract)類具有如下特點:抽象類中可以有abstract方法,也可以有非abstract方法。抽象類不能用new運算符創(chuàng)建對象。如果一個非抽象類是某個抽象類的子類,那么它必須重寫父類的abstract方法,即在子類中將abstract方法重新聲明,但必須去掉abstract修飾符,同時要保證聲明的方法名字、返回類型、參數(shù)個數(shù)和類型與父類的abstract方法完全相同。盡管抽象類不能用new運算符創(chuàng)建對象,但它的非abstract子類必須要重寫它中的全部abstract方法,這樣一來,就可以讓抽象類聲明的對象成為其子類對象的上轉(zhuǎn)型對象,并調(diào)用子類重寫的方法。第三部分面向?qū)ο蟮膸讉€基本原則

3.1面向抽象原則25(1)抽象類

publicabstractclassA{publicabstractintadd(intx,inty);}publicBextendsA{publicintadd(intx,inty){returnx+y;}}publicApplication{publicstaticvoidmain(Stringargs[]){Aa;a=newB();//a是B類對象的上轉(zhuǎn)型對象intm=a.add(3,2);……}(1)抽象類publicabstractclassA26(2)接口接口(interface)具有如下特點:接口中只可以有public權(quán)限的abstract方法,不能有非abstract方法。接口由類去實現(xiàn),即一個類如果實現(xiàn)一個接口,那么它必須重寫接口中的abstract方法,即將abstract方法重新聲明,但必須去掉abstract修飾符,同時要保證聲明的方法名字、返回類型、參數(shù)個數(shù)和接口中的方法完全相同。接口回調(diào)。接口回調(diào)是指可以把實現(xiàn)接口的類的對象的引用賦給該接口聲明的接口變量中,那么該接口變量就可以調(diào)用被類實現(xiàn)的接口中的方法,當接口變量調(diào)用被類實現(xiàn)的接口中的方法時,就是通知相應的對象調(diào)用接口的方法,這一過程稱為對象方法的接口回調(diào)。(2)接口27(2)接口publicinterfaceCom{publicabstractintsub(intx,inty);}ClassComImpimplementsCom{publicintsub(intx,inty){returnx-y;}}publicApplication{publicstaticvoidmain(Stringargs[]){Comcomcom=newComImp();//com變量存放ComImp類對象的引用

intm=com.sub(5,2);//com回調(diào)ComImp類實現(xiàn)的接口方法system.out.println(m);}}(2)接口publicinterfaceCom{28

3.1面向抽象原則所謂面向抽象編程,是指當設(shè)計一個類時,不讓該類面向具體的類,而是面向抽象類或接口,即所設(shè)計類中的重要數(shù)據(jù)是抽象類或接口聲明的變量,而不是具體類聲明的變量。3.1面向抽象原則所謂面向抽象編程,是指當設(shè)293.2開-閉原則所謂“開-閉原則”(Open-ClosedPrinciple)就是讓你的設(shè)計應當對擴展開放,對修改關(guān)閉。實際上這句話的本質(zhì)是指當一個設(shè)計中增加新的模塊時,不需要修改現(xiàn)有的模塊。我們在給出一個設(shè)計時,應當首先考慮到用戶需求的變化,將應對用戶變化的部分設(shè)計為對擴展開放,而設(shè)計的核心部分是經(jīng)過精心考慮之后確定下來的基本結(jié)構(gòu),這部分應當是對修改關(guān)閉的,即不能因為用戶的需求變化而再發(fā)生變化,因為這部分不是用來應對需求變化的。3.2開-閉原則所謂“開-閉原則”(Open30如果您的設(shè)計遵守了“開-閉原則”,那么這個設(shè)計一定是易維護的,因為在設(shè)計中增加新的模塊時,不必去修改設(shè)計中的核心模塊。比如,我們在2.1節(jié)給出的設(shè)計中有4個類,類圖如下:如果您的設(shè)計遵守了“開-閉原則”,那么這個設(shè)計一定是易維護的31通常我們無法讓設(shè)計的每個部分都遵守“開-閉原則”,甚至不應當這樣去做,我們應當把主要精力集中在應對設(shè)計中最有可能因需求變化而需要改變的地方,然后想辦法應用“開-閉原則”。當設(shè)計某些系統(tǒng)時,我們經(jīng)常需要面向抽象來考慮系統(tǒng)的總體設(shè)計,不要考慮具體類,這樣就容易設(shè)計出滿足“開-閉原則”的系統(tǒng),在程序設(shè)計好后,首先對abstract類的修改關(guān)閉,否則,一旦修改abstract類,比如,為它再增加一個abstract方法,那么abstract類所有的子類都需要做出修改;應當對增加abstract類的子類開放,即在程序中再增加子類時,不需要修改其它面向抽象類而設(shè)計的重要類。通常我們無法讓設(shè)計的每個部分都遵守“開-閉原則”,323.3多用組合少用繼承原則之所以提倡多用組合,少用繼承,是因為在許多設(shè)計中,人們希望系統(tǒng)的類之間盡量是低耦合的關(guān)系,而不希望是強偶合關(guān)系。即在許多情況下需要避開繼承的缺點,而需要組合的優(yōu)點。怎樣合理地使用組合,而不是使用繼承來獲得方法的復用需要經(jīng)過一定時間的認真思考、學習和編程實踐才能悟出其中的道理,這也是促使我們學習設(shè)計模式的原因之一。關(guān)于多用組合,少用繼承,在后面的設(shè)計模式中,比如裝飾模式,策略模式以中介者模式中都有體現(xiàn)。

3.3多用組合少用繼承原則之所以提倡多用組合333.4高內(nèi)聚-低耦合原則

如果類中的方法是一組相關(guān)的行為,則稱該類是高內(nèi)聚的,反之稱為低內(nèi)聚的。高內(nèi)聚便于類的維護,而低內(nèi)聚不利于類的維護,學習后面迭代器模式時,會更深刻體會到這一原則。所謂低耦合就是盡量不要讓一個類含有太多的其它類的實例的引用,以避免修改系統(tǒng)的其中一部分會影響到其它部分,比如在后面學習中介者模式時,就會體會到這一原則。模式設(shè)計參考網(wǎng)站:/3.4高內(nèi)聚-低耦合原則如果類中的方法是一組34第四部分23種設(shè)計模式命令模式?別名?動作?事務)Commandpattern將一個請求封裝為一個對象?從而使用戶可用不同的請求對客戶進行參數(shù)化?對請求排隊或記錄請求日志?以及支持可撤銷的操作。第四部分23種設(shè)計模式命令模式?別名?動作?事務)Com35命令模式中的四種角色接收者(Receiver):是一個類的實例,該實例負責請求與執(zhí)行相關(guān)的操作。命令接口(Command):規(guī)定了用來封裝請求的若干方法,如execute(),undo().具體命令(ConcreteCommand):是實現(xiàn)命令接口的具體實例請求者(Invoke):是一個包含Command接口變量的類的實例。命令模式中的四種角色接收者(Receiver):是一個類的實36命令模式對應的四種角色命令模式對應的四種角色37命令模式的UML類圖命令模式的UML類圖38命令模式的代碼實現(xiàn)publicinterfaceCommand{publicabstractvoidexecute();}publicclassConcreteCommandimplementsCommand{CompanyArmyarmy;//含有接收者的引用ConcreteCommand(CompanyArmyarmy){this.army=army;}publicvoidexecute(){//封裝著指揮官的請求army.sneakAttack();//偷襲敵人}}命令模式的代碼實現(xiàn)publicinterfaceCo39命令模式的代碼實現(xiàn)publicclassCompanyArmy{publicvoidsneakAttack(){System.out.println("我們知道如何偷襲敵人,保證完成任務");}}

publicclassArmySuperior{Commandcommand;//用來存放具體命令的引用publicvoidsetCommand(Commandcommand){mand=command;}publicvoidstartExecuteCommand(){command.execute();}}命令模式的代碼實現(xiàn)publicclassCompan40命令模式的代碼實現(xiàn)publicclassApplication{publicstaticvoidmain(Stringargs[]){CompanyArmy三連=newCompanyArmy();//創(chuàng)建接收者Commandcommand=newConcreteCommand(三連);//創(chuàng)建具體命令并指定接收者ArmySuperior指揮官=newArmySuperior();//創(chuàng)建請求者指揮官.setCommand(command);指揮官.startExecuteCommand();}}命令模式的代碼實現(xiàn)publicclassApplicat41命令接口中的撤銷操作命令接口中的撤銷操作42策略模式StrategyPattern

策略模式(別名:政策Police)

定義一系列算法,把它們一個個封裝起來,并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。

策略模式StrategyPattern策略模式(43策略模式概述1.類中一個方法的方法體由一系列語句構(gòu)成,方法的方法體是一個算法。2.比如,Army類,該類中有一個int型數(shù)組,數(shù)組元素的值代表士兵的號碼,該類中有l(wèi)ineUp(),該方法將士兵按他們的號碼從小到大排隊.3.Army類創(chuàng)建的任何對象,比如“三連長”,“四連長”等,調(diào)用lineUp()方法只能將自己所管理的士兵按其號碼從小到大排隊.4.需求變化。需求變化可能導致經(jīng)常需要修改類中某個方法的方法體,即修改算法。有些部隊希望Army創(chuàng)建的“連長”能將士兵按著他們的號碼從大到小排隊(不是從小到大),或?qū)⑹勘粗麄兊奶柎a的某種排列來排隊。策略模式概述1.類中一個方法的方法體由一系列語句構(gòu)成,方法的44策略模式概述5.問題出現(xiàn)。Army無法提供這樣的對象(設(shè)計不合理).6.不正確地解決問題。痛苦地修改lineUp()的方法體,但馬上就發(fā)現(xiàn)這樣做也不行,因為一旦將lineUp()的方法體修改成把士兵按著他們的號碼從大到小來排隊,那么又無法滿足某些部隊希望Army創(chuàng)建的“連長”能將自己的士兵從小到大排序;也許我們可以在lineUp()方法中添加多重條件語句,以便根據(jù)用戶的具體需求決定怎樣排隊,但這也不是一個好辦法,因為只要一旦有新的需求,就要修改lineUp()方法添加新的判斷語句,而且針對某個條件語句的排隊代碼也可能因該用戶的需求變化導致重新編寫。

策略模式概述5.問題出現(xiàn)。Army無法提供這樣的對象(設(shè)計不457.我們發(fā)現(xiàn)問題的實質(zhì):問題的癥結(jié)就是Army類的lineUp()方法體中的代碼(具體算法)需要經(jīng)常地發(fā)生變化。8.尋找解決辦法。面向?qū)ο缶幊逃幸粋€很好的設(shè)計原則:“面向抽象編程”,該原則的核心就是將類中經(jīng)常需要變化的部分分割出來,并將每種可能的變化對應地交給抽象類的一個子類或?qū)崿F(xiàn)接口的一個類去負責,從而讓類的設(shè)計者不去關(guān)心具體實現(xiàn),避免所設(shè)計的類依賴于具體的實現(xiàn)。

現(xiàn)在,我們面向接口(抽象類)來重新設(shè)計Army類,讓Army類依賴于Strategy接口,即Army類含有一個Strategy接口聲明的變量,并重新編寫lineUp()的方法體中的代碼,其主要代碼是委托Army類中的Strategy接口變量調(diào)用arrange(int[]a)方法,類圖如圖1.4

策略模式概述7.我們發(fā)現(xiàn)問題的實質(zhì):問題的癥結(jié)就是Army類的lineU46策略模式UML類圖策略模式UML類圖479.總結(jié)出辦法:策略模式。策略模式是處理算法的不同變體的一種成熟模式,策略模式通過接口或抽象類封裝算法的標識,即在接口中定義一個抽象方法,實現(xiàn)該接口的類將實現(xiàn)接口中的抽象方法。策略模式把針對一個算法標識的一系列具體算法分別封裝在不同的類中,使得各個類給出的具體算法可以相互替換。在策略模式中,封裝算法標識的接口稱作策略,實現(xiàn)該接口的類稱作具體策略。以下給出策略模式的類圖,并詳細闡述該模式中各個角色的職責。策略模式概述9.總結(jié)出辦法:策略模式。策略模式是處理算法的不同變體的一種48策略模式的結(jié)構(gòu)中包括三種角色:策略(Strategy):策略是一個接口,該接口定義若干個算法標識,即定義了若干個抽象方法。具體策略(ConcreteStrategy):具體策略是實現(xiàn)策略接口的類。具體策略實現(xiàn)策略接口所定義的抽象方法,即給出算法標識的具體算法。上下文(Context):上下文是依賴于策略接口的類,即上下文包含有策略聲明的變量。上下文中提供一個方法,該方法委托策略變量調(diào)用具體策略所實現(xiàn)的策略接口中的方法。策略模式的角色策略模式的結(jié)構(gòu)中包括三種角色:策略模式的角色49策略模式的UML類圖策略模式的UML類圖50publicinterfaceComputableStrategy{publicabstractdoublecomputeScore(double[]a);}publicclassStrategyOneimplementsComputableStrategy{publicdoublecomputeScore(double[]a){doublescore=0,sum=0;for(inti=0;i<a.length;i++){sum=sum+a[i];}score=sum/a.length;returnscore;}}publicinterfaceComputableSt51publicclassGymnasticsGame{ComputableStrategystrategy;publicvoidsetStrategy(ComputableStrategystrategy){this.strategy=strategy;}publicdoublegetPersonScore(double[]a){if(strategy!=null)returnputeScore(a);elsereturn0;}}publicclassGymnasticsGame{52publicclassApplication{publicstaticvoidmain(Stringargs[]){GymnasticsGamegame=newGymnasticsGame();//上下文對象game.setStrategy(newStrategyOne());//上下文對象使用…..publicclassApplication{53策略模式的優(yōu)點上下文(Context)和具體策略(ConcreteStragy)是松耦合關(guān)系策略模式滿足“開-閉原則”滿足需要使用一個算法的不同變體。策略模式的優(yōu)點上下文(Context)和具體策略(Concr54裝飾模式DecoratorPattern

別名:包裝器Wrapper動態(tài)地給對象添加一些額外的職責。就功能來說裝飾模式相比生成子類更為靈活。

裝飾模式DecoratorPattern別名:55裝飾模式概述1.在許多設(shè)計中,可能需要改進類的某個對象的功能,而不是該類創(chuàng)建的全部對象。2.比如,麻雀類的實例(麻雀)能連續(xù)飛行100米,如果我們用麻雀類創(chuàng)建了5只麻雀,那么這5只麻雀都能連續(xù)飛行100米。3.需求變化。假如想讓其中一只麻雀能連續(xù)飛行150米,那應當怎樣做呢?我們不想通過修改麻雀類的代碼(也可能根本不允許我們修改)使得麻雀類創(chuàng)建的麻雀都能連續(xù)飛行150米,這也不符合需求:改進類的某個對象的功能。4.不正確地解決問題裝飾模式概述1.在許多設(shè)計中,可能需要改進類的某個對象的功能56裝飾模式概述5.尋找解決辦法。一種比較好的辦法就是給麻雀裝上智能電子翅膀。智能電子翅膀可以使得麻雀不使用自己的翅膀就能飛行50米。那么一只安裝了這種智能電子翅膀的麻雀就能飛行150米,因為麻雀首先使用自己的翅膀飛行100米,然后電子翅膀開始工作再飛行50米。6.正確的解決辦法:裝飾模式。裝飾模式是動態(tài)地擴展一個對象的功能,而不需要改變原始類代碼的一種成熟模式。。裝飾模式概述5.尋找解決辦法。一種比較好的辦法就是給麻雀裝上577.關(guān)鍵術(shù)語。(1)具體組件具體組件稱作“被裝飾者”。(2)具體裝飾具體裝飾稱為“裝飾者”。8.關(guān)鍵技術(shù)“具體裝飾”需要包含有“具體組件”的一個實例的引用,以便裝飾“被裝飾者”。如圖2.1。7.關(guān)鍵術(shù)語。58麻雀類就是“具體組件”,而一只麻雀就是“具體組件”的一個實例,即是一個“被裝飾者”,而按裝了電子翅膀的麻雀就是“具體裝飾”的一個實例,即按裝了電子翅膀的麻雀就是麻雀的“裝飾者”。比如,麻雀類有一個fly方法,麻雀類的實例調(diào)用fly能飛行100米,如圖2.2

麻雀類就是“具體組件”,而一只麻雀就是“具體組件59“具體裝飾”類的fly方法能飛行150米,裝飾類的eleFly方法能飛行50米,麻雀類的fly方法能飛行100米?!熬唧w裝飾”類的實例調(diào)用fly麻雀類的fly方法能飛100米。調(diào)用fly圖2.2麻雀類的fly方法麻雀類的實例“具體裝飾”也有一個和麻雀類同名的fly()方法,另外還有一個自己獨特的新方法eleFly()方法。由于“具體裝飾”類包含有一只麻雀的引用,因此“具體裝飾”類可以將它的fly()方法實現(xiàn)為:首先委托麻雀調(diào)用fly()方法飛行100米,然后再調(diào)用eleFly()方法飛行50米。因此,“具體裝飾”類的實例調(diào)用fly()方法能飛行150米,如圖2.3?!熬唧w裝飾”類的fly方法能飛行150米,裝飾60裝飾模式的結(jié)構(gòu)中包括四種角色:抽象組件(Component):抽象組件是一個抽象類。抽象組件定義了“被裝飾者”需要進行“裝飾”的方法。具體組件(ConcreteComponent):具體組件是抽象組件的一個子類,具體組件的實例稱作“被裝飾者”。裝飾(Decorator):裝飾是抽象組件的一個子類,裝飾包含有一個抽象組件聲明的變量以保存“被裝飾者”的引用。裝飾可以是抽象類也可以是一個非抽象類,如果是非抽象類,那么該類的實例稱作“裝飾者”。具體裝飾(ConcreteDecotator):具體裝飾是裝飾的一個非抽象子類,具體裝飾的實例稱作“裝飾者”。裝飾模式的角色裝飾模式的結(jié)構(gòu)中包括四種角色:裝飾模式的角色61裝飾模式的UML類圖裝飾模式的UML類圖62裝飾模式的程序舉例publicabstractclassBird{publicabstractintfly();}publicclassSparrowextendsBird{publicfinalintDISTANCE=100;publicintfly(){returnDISTANCE;}}裝飾模式的程序舉例publicabstractclass63裝飾模式的程序舉例publicabstractclassDecoratorextendsBird{protectedBirdbird;publicDecorator(){}publicDecorator(Birdbird){this.bird=bird;}}裝飾模式的程序舉例publicabstractclass64publicclassSparrowDecoratorextendsDecorator{publicfinalintDISTANCE=50;//eleFly方法能飛50米SparrowDecorator(Birdbird){super(bird);}publicintfly(){intdistance=0;distance=bird.fly()+eleFly();returndistance;}privateinteleFly(){//裝飾者新添加的方法returnDISTANCE;}}publicclassSparrowDecorator65publicclassApplication{publicvoidneedBird(Birdbird){intflyDistance=bird.fly();System.out.println("這只鳥能飛行"+flyDistance+"米");}publicstaticvoidmain(Stringargs[]){Applicationclient=newApplication();Sparrowsparrow=newSparrow();SparrowDecoratorsparrowDecorator1=newSparrowDecorator(sparrow);SparrowDecoratorsparrowDecorator2=newSparrowDecorator(sparrowDecorator1);client.needBird(sparrowDecorator1);client.needBird(sparrowDecorator2);}}publicclassApplication{66觀察者模式(Observerpattern)觀察者模式(別名:依賴,發(fā)布-訂閱)定義對象間的一種一對多的依賴關(guān)系,當一個對象的狀態(tài)發(fā)生變化時,所有依賴它的對象得到通知并被自動改變。觀察者模式是關(guān)于多個對象想知道一個對象中數(shù)據(jù)變化情況的一種成熟的模式。觀察者模式中有一個稱作“主題”的對象和若干個稱作“觀察者”的對象。觀察者模式(Observerpattern)觀察者模式(別67觀察者模式(Observerpattern)觀察者模式的結(jié)構(gòu)中包括四種角色:主題:是一個接口,該接口規(guī)定了具體主題需要實現(xiàn)的方法,比如:添加、刪除觀察者,以及通知觀察者更新數(shù)據(jù)的方法。觀察者:是一個接口,該接口規(guī)定了具體觀察者用來更新數(shù)據(jù)的方法。具體主題:是實現(xiàn)主題接口類的一個實例,該實例包括有可能經(jīng)常發(fā)生變化的數(shù)據(jù)。具體觀察者:是觀察者接口的一個實例。觀察者模式(Observerpattern)觀察者模式的結(jié)68觀察者模式(Observerpattern)觀察者類圖:

<<interface>>Subject+addObserver(Observer):void+deleteObserver():void+deleteObserver():void<<interface>>Observer+update():voidConcreateObserverSubject:subject+update():voidConcreteSubject+addObserver(Observer):void+deleteObserver():void+deleteObserver():voidotherMetond():void觀察者模式(Observerpattern)觀察者類圖:<69享元模式(FlyweightPattern)運用共享技術(shù)有效地支持大量細粒度對象。關(guān)鍵是使用一個稱作享元的對象為其它對象提供共享的狀態(tài),而且能夠保證使用享元的對象不能更改享元中的數(shù)據(jù)。CarDataHeight:doubleWidth:doubleLength:doubleCarcardata:CarDatacolor:stringpower:double享元模式(FlyweightPattern)運用共享技術(shù)有70享元模式包括三種角色享元接口(Flyweight):定義享元對外公開其內(nèi)部數(shù)據(jù)的方法,以及享元接收外部數(shù)據(jù)的方法。具體享元(ConcreteFlyweight)實現(xiàn)享元接口的具體的類。享元工廠(FlyweightFactory)是一個類,該類的實例負責創(chuàng)建和管理享元對象,用戶或其他對象必須請求享元工廠為它得到一個享元對象。享元模式(FlyweightPattern)享元模式包括三種角色享元模式(FlyweightPatte71享元模式(FlyweightPattern)FlyweightFactory-hashMap:HashMap+getFlyweight(Stringkey):FlyweightConcreateFlyweight-intrinsicState:int+operation(intextrinsicState)Flyweight<interface>+operation(intextrinsicState)享元模式(FlyweightPattern)Flyweig72備忘錄模式(MementoPatten)別名?標記Token在不破壞封裝性的前提下?捕獲一個對象的內(nèi)部狀態(tài)?并在該對象之外保存這個狀態(tài)?這樣以后就可將該對象恢復到原先保存的狀態(tài)。在備忘錄模式中?稱需要保存的狀態(tài)為“原發(fā)者”?稱負責保存原發(fā)者狀態(tài)的對象為“備忘錄”?稱負責管理備忘錄的對象為“負責人”。備忘錄模式(MementoPatten)別名?標記Tok73備忘錄模式(MementoPatten)備忘錄模式包括的三種角色:原發(fā)者:需要在某個時刻保存其狀態(tài)的對象。備忘錄:負責存儲原發(fā)者狀態(tài)的對象。負責人:負責管理保存?zhèn)渫浀膶ο驩riginatorState:int+creaeMemento():Memento+restoreFormMemento(Memento):voidMenento+getState():intsetState(intm):voidCaretaker備忘錄模式(MementoPatten)備忘錄模式包括的三74責任鏈模式使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收到者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。責任鏈械結(jié)構(gòu)中包括兩種角色處理者,是一個接口,負責規(guī)定具體處理者處理用戶請求的方法,具體處理者設(shè)置后繼的方法具體處理者,實現(xiàn)處理者接口類的實現(xiàn)責任鏈模式使多個對象都有機會處理請求,從而避免請求的發(fā)送者和75責任鏈模式<interface>Handler+handleRequst():void+setNextHandler(Handler):voidConcreteHandler1+handleRequst():void+setNextHandler(Handler):voidConcreteHandler1+handleRequst():void+setNextHandler(Handler):void責任鏈模式<interface>+handleRequst76工廠方法模式別名:虛擬構(gòu)造定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。工廠方法的關(guān)鍵是在一個接口或抽象類中定義一個抽象方法,該方法返回某個類的子類的實例,該接口或抽象類讓其實現(xiàn)方法或子類通過重寫這個抽象方法返回某個子類的實例。角色有:抽象產(chǎn)品,具體產(chǎn)品,構(gòu)造者和具體要構(gòu)造者。工廠方法模式別名:虛擬構(gòu)造77工廠方法模式類圖<interface>Creator+factoryMethod():Product<interface>ProductConcreteCreator1+factoryMethod():ProductConcreteCreator2+factoryMethod():ProductProduct1Product2工廠方法模式類圖<interface>+factoryMe78JAVA集合框架與工廠模式<interface>Collection+iterator():IteratorLinkedList+iterator():IteratorHashSet+iterator():Iterator<interface>Iterator+hasNext():boolean+next():Object+remove():voidJAVA集合框架與工廠模式<interface>+iter79抽象工廠模式別名:配套Kit提供一個創(chuàng)建一系列或相互依賴對象的接口,而無須指定它們具體的類。當系統(tǒng)準備為用戶提供一系列相關(guān)的對象,又不想讓用戶代碼和創(chuàng)建這些對象的類形成耦合,就可以使用抽象工廠方法模式來設(shè)計系統(tǒng)。抽象工廠模式的關(guān)鍵是在一個抽象類或接口中定義若干個抽象方法,這些方法分別返回某個類的實例。然后由子類或?qū)崿F(xiàn)類重寫這些抽象方法為用戶提供一系例相關(guān)的對象。抽象工廠模式別名:配套Kit80抽象工廠模式類圖AbatractFactory+createProductA():ProductA+createProductB():ProductBAbatractFactory1+createProductA():ProductA+createProductB():ProductBAbatractFactory2+createProductA():ProductA+createProductB():ProductBProductAProductA1ProductA2ProductBProductB1ProductB2抽象工廠模式類圖AbatractFactory+create81關(guān)于銀行存款憑證設(shè)計用戶在銀行存款后,用戶將得到銀行給予的存款憑證,該存款憑證就是加蓋了業(yè)務公章的存款明細抽象工廠publicabstractclassBank{publicabstractDepositSlipcreateDepositSlip(Stringnumber,Stringname,intmoney);publicabstractSealcreateSeal();}關(guān)于銀行存款憑證設(shè)計用戶在銀行存款后,用戶82具體工廠publicclassBankOfCommunicationsextendsBank{publicDepositSlipcreateDepositSlip(Stringnumber,Stringname,intmoney){returnnewDepositSlip3(number,name,money);}publicSealcreateSeal(){returnnewSealThree();}}具體工廠83publicclassChinaBankextendsBank{publicDepositSlipcreateDepositSlip(Stringnumber,Stringname,intmoney){returnnewDepositSlip1(number,name,money);}publicSealcreateSeal(){returnnewSealOne();}}publicclassChinaBankextends84publicclassChinaConstructionBankextendsBank{publicDepositSlipcreateDepositSlip(Stringnumber,Stringname,intmoney){returnnewDepositSlip2(number,name,money);}publicSealcreateSeal(){returnnewSealTwo();}}publicclassChinaConstruction85抽象產(chǎn)品publicinterfaceDepositSlip{publicabstractStringgetBankName();publicabstractStringgetClientName();publicabstractStringgetClientNumber();publicabstractintgetAmountOfMoney();}importjava.awt.*;publicinterfaceSeal{publicabstractImagegetImage();}抽象產(chǎn)品publicinterfaceDepositSl86具體產(chǎn)品publicclassDepositSlip1implementsDepositSlip{StringclientNumber;StringclientName;intmoney;DepositSlip1(StringclientNumber,StringclientName,intmoney){this.clientNumber=clientNumber;this.clientName=clientName;this.money=money;}具體產(chǎn)品87publicStringgetBankName(){return"中國銀行";}publicStringgetClientName(){returnclientName;}publicStringgetClientNumber(){returnclientNumber;}publicintgetAmountOfMoney(){returnmoney;}}publicStringgetBankName(){88publicclassDepositSlip2implementsDepositSlip{StringclientNumber;StringclientName;intmoney;DepositSlip2(StringclientNumber,StringclientName,intmoney){this.clientNumber=clientNumber;this.clientName=clientName;this.money=money;}publicStringgetBankName(){return"中國建設(shè)銀行";}publicStringgetClientName(){returnclientName;}publicStringgetClientNumber(){returnclientNumber;}publicintgetAmountOfMoney(){returnmoney;}}publicclassDepositSlip2impl89publicclassDepositSlip3implementsDepositSlip{StringclientNumber;StringclientName;intmoney;DepositSlip3(StringclientNumber,StringclientName,intmoney){this.clientNumber=clientNumber;this.clientName=clientName;this.money=money;}publicStringgetBankName(){return“中國農(nóng)業(yè)銀行";}publicStringgetClientName(){returnclientName;}publicStringgetClientNumber(){returnclientNumber;}publicintgetAmountOfMoney(){returnmoney;}}publicclassDepositSlip3impl90importjavax.swing.*;importjava.awt.*;publicclassShowDepositSlipextendsJPanel{DepositSlipdepositSlip;Sealseal;booleanboo;JLabellabel;Imageimage;JFrameframe;ShowDepositSlip(){setLayout(null);setSize(200,200);label=newJLabel();add(label);frame=newJFrame();frame.add(this);}……importjavax.swing.*;91publicclassApplication{publicstaticvoidmain(Stringargs[]){ShowDepositSlipshowDepositSlip=newShowDepositSlip();Bankbank=newChinaBank();showDepositSlip.showDepositSlip(bank,"298765423","張三",5000);showDepositSlip.setLocation(20,20);showDepositSlip=newShowDepositSlip();bank=newChinaConstructionBank();showDepositSlip.showDepositSlip(bank,"128700542","李四",3000);showDepositSlip.setLocation(240,20);showDepositSlip=newShowDepositSlip();bank=newBankOfCommunications();showDepositSlip.showDepositSlip(bank,"108765469","孫五",8000);showDepositSlip.setLocation(460,20);}}publicclassApplication{92組合模式將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。并使用戶對單個對象和組合對象的使用具有一致性。組合模式將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。93組合模式的類圖<<interface>>Component+add(Component):void+remove(Component):void+getChild(int):Component+opration():voidCompositeChile:LinkedList+add(Component):void+remove(Component):void+getChild(int):Component+opration():voidLeaf+oprationt():void組合模式的類圖<<interface>>+add(Comp94解釋器模式給定一種語言,定義它的方法的一種表示,并定義一個解釋器,這個解釋器使用該表示解釋語言中的句子。對于某些問題,我們可能希望用簡單的語言來描述,既希望用簡單語言實現(xiàn)簡單的翻譯操作。語言是由語句組成的集合,而語句是由一組符號所構(gòu)成的序列。解釋器模式給定一種語言,定義它的方法的一種表示,并定義一個解95解釋器的UML類圖<interface>AbstractExpression+parse(Context):void+execute():voidTerminalExpression+parse(Context):void+execute():voidNonTerminalExpression+parse(Context):void+execute():voidContext解釋器的UML類圖<interface>+parse(Co96簡單的英文翻譯器<Stentence>::=<Subject><Predicate><Predicate>::=<Verb><Object><Object>::=<SubjectPronoun>|<Noun><SubjectPronoun>::=You|He|…|They<Noun>::=Teacher|Student|Tiger…|book<Verb>::=Drink|Run|Insruct…|Receive簡單的英文翻譯器<Stentence>::=<Subject97abstractExpressionpublicinterfaceNode{publicvoidparse(Context);publicvoidexecute();}NonTerminalExpressionpublicclassSentenceNodeimplementsNode{NodesubjectNode,predicateNodepublicvoidparse(Contextcontext){…abstractExpression98subjectNode=newSubjectNode();predicateNode=newPredicateNode();subjectNode.parse(context);predicateNode.parse(context);}publicvoidexecute(){subjectNode.execute();predicateNode.execute();}}subjectNode=newSub99TerminalExpressionpublicclassVerbNodeimplementsNode{String[]word={"Drink","Eat","Look","beat"};Stringtoken;booleanboo;publicvoidparse(Contextcontext){token=context.nextToken();inti=0;for(i=0;i<word.length;i++){if(token.equalsIgnoreCase(word[i])){boo=true;break;}}if(i==word.length)boo=false;}TerminalExpression100

publicvoidexecute(){if(boo){if(token.equalsIgnoreCase(word[0]))System.out.print("喝");if(token.equalsIgnoreCase(word[1]))System.out.print("吃");if(token.equalsIgnoreCase(word[2]))System.out.print("看");if(token.equalsIgnoreCase(word[3]))System.out.print("打");}else{System.out.print(token+"(不是該語言中的句子)");}}}

101contextimportjava.util.StringTokenizer;publicclassContext{StringTokenizertokenizer;Stringtoken;publicContext(Stringtext){setContext(text);}publicvoidsetContext(Stringtext){tokenizer=newStringTokenizer(text);}StringnextToken(){if(tokenizer.hasMoreTokens()){token=tokenizer.nextToken();}elsetoken="";returntoken;}}context102publicclassApplication{publicstaticvoidmain(Stringargs[]){Stringtext="Teacherbeattiger";Contextcontext=newContext(text);Nodenode=newSentenceNode();node.parse(context);node.execute();text="Youeatapple";context.setContext(text);System.out.println();node.parse(context);node.execute();text="youlookhim";context.setContext(text);System.out.println();node.parse(context);node.execute();}}publicclassApplication{103第一部分設(shè)計模式簡介

一、什么是設(shè)計模式1.

溫馨提示

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

評論

0/150

提交評論