23種設(shè)計(jì)模式詳解課件_第1頁
23種設(shè)計(jì)模式詳解課件_第2頁
23種設(shè)計(jì)模式詳解課件_第3頁
23種設(shè)計(jì)模式詳解課件_第4頁
23種設(shè)計(jì)模式詳解課件_第5頁
已閱讀5頁,還剩75頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

設(shè)計(jì)模式詳解設(shè)計(jì)模式詳解1何謂設(shè)計(jì)模式在面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)過程中,我們經(jīng)常會(huì)遇到很多重復(fù)出現(xiàn)的問題,總結(jié)解決這些問題的成功經(jīng)驗(yàn)和最佳實(shí)踐便形成了設(shè)計(jì)模式(DesignPattern)。其核心思想是將可重用的解決方案總結(jié)出來,并分門別類。從而指導(dǎo)設(shè)計(jì),減少代碼重復(fù)和優(yōu)化體系結(jié)構(gòu)。何謂設(shè)計(jì)模式在面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)過程2采用設(shè)計(jì)模式的益處重用,避免代碼重復(fù)冗余優(yōu)化體系結(jié)構(gòu)提升系統(tǒng)的可維護(hù)性和彈性代碼更加容易測試,利于測試驅(qū)動(dòng)為性能優(yōu)化提供便利使軟件質(zhì)量更加有保證增強(qiáng)代碼可讀性,便于團(tuán)隊(duì)交流有助于整體提升團(tuán)隊(duì)水平采用設(shè)計(jì)模式的益處重用,避免代碼重復(fù)冗余3設(shè)計(jì)模式、重構(gòu)和Antiparttern設(shè)計(jì)模式是成功經(jīng)驗(yàn)和最佳實(shí)踐的總結(jié),指導(dǎo)設(shè)計(jì)人員采用正確精良的設(shè)計(jì)。重構(gòu)(Refactor)專注于軟件的漸進(jìn)完善。通過消除重復(fù)冗余代碼,并將存在體系結(jié)構(gòu)缺陷的代碼重新構(gòu)建成符合設(shè)計(jì)模式的代碼來達(dá)到設(shè)計(jì)精良軟件的目的。Antiparttern與設(shè)計(jì)模式相反,是失敗教訓(xùn)的總結(jié)。其澄清了許多設(shè)計(jì)中經(jīng)常面臨的陷阱和容易混淆的問題,能有效防止開發(fā)人員犯錯(cuò)誤,從而做出正確選擇。設(shè)計(jì)模式、重構(gòu)和Antiparttern設(shè)計(jì)模式是成功經(jīng)驗(yàn)和4設(shè)計(jì)模式與UML設(shè)計(jì)模式是OOP的方法論,其內(nèi)容描述基本是圍繞對象的結(jié)構(gòu)和協(xié)作關(guān)系設(shè)計(jì)。因此需要一種直觀的模型將上述內(nèi)容清晰地表示出來。統(tǒng)一建模語言(UML)是OOP的建模語言,其核心就是把軟件的設(shè)計(jì)思想通過建模的方法表達(dá)出來。故非常適合于表達(dá)設(shè)計(jì)模式。同時(shí)UML已經(jīng)被廣泛用于軟件設(shè)計(jì),這也推動(dòng)了設(shè)計(jì)模式的應(yīng)用。設(shè)計(jì)模式與UML設(shè)計(jì)模式是OOP的方法論,其內(nèi)容5設(shè)計(jì)模式分類Creationalpatterns幫助我們更好地組織創(chuàng)建對象的代碼。增強(qiáng)彈性,以應(yīng)付在不同情況下創(chuàng)建和初始化對象的代碼變更。Structuralpatterns增強(qiáng)代碼重用,優(yōu)化對象結(jié)構(gòu),使其職責(zé)分明、粒度合適,以松耦合的體系結(jié)構(gòu)來減低代碼的rippling效應(yīng)。Behavioralpatterns更好地定義對象間的協(xié)作關(guān)系,使復(fù)雜的程序流程變得清晰。設(shè)計(jì)模式分類Creationalpatterns幫助我們6CreationalPatternsTheFactoryPatternTheAbstractFactoryPatternTheSingletonPatternThePrototypePatternCreationalPatternsTheFactory7TheFactoryPattern

Factory是最常見的設(shè)計(jì)模式之一,可幫助我們組織創(chuàng)建對象的代碼,通常用于以下兩種情況:

創(chuàng)建復(fù)雜的對象,并進(jìn)行初始化。根據(jù)不同的環(huán)境(輸入?yún)?shù)),創(chuàng)建不同用途的對象。一般這些對象都是實(shí)現(xiàn)了相同的接口或繼承于同一基類。TheFactoryPattern Factor8Factory模式的JDBC應(yīng)用OracleDataSource負(fù)責(zé)創(chuàng)建鏈接,由函數(shù)getConnection獲取鏈接Factory模式的JDBC應(yīng)用OracleDataSour9Factory模式應(yīng)用于DAO

XMLDB是XML數(shù)據(jù)庫訪問接口,針對Oracle和DB2分別提供了實(shí)現(xiàn)。XMLDB_DAOFactory為類工廠,根據(jù)輸入的參數(shù)dbtype,創(chuàng)建不同的XMLDB實(shí)現(xiàn)類。Factory模式應(yīng)用于DAOXMLDB是XML數(shù)10更多的Factory模式應(yīng)用例子Hibernate的SessionFactory,將數(shù)據(jù)庫表和對象的映射關(guān)系寫入XML格式的配置文件,然后由SessionFactory根據(jù)它來創(chuàng)建Session。EJB容器本身就是一個(gè)EJB的Factory。當(dāng)客戶端調(diào)用EJB的時(shí)候,由容器創(chuàng)建EJB供其使用。更多的Factory模式應(yīng)用例子Hibernate的Ses11TheAbstractFactoryPattern在介紹AbstractFactory之前,先回顧下Factory模式的JDBC應(yīng)用。由于很多系統(tǒng)需要訪問不同的數(shù)據(jù)庫,故在得到Connection之前要獲取不同的DataSource。于是我們又遇到了Factory模式所要解決的問題:創(chuàng)建一個(gè)Factory來獲取不同的DataSource。而DataSource本身又是一個(gè)Factory。

由上述我們不難引出AbstractFactory的定義,就是用于創(chuàng)建Factory的Factory。其設(shè)計(jì)思想和Factory的完全一致,不過是一種特殊的Factory而已。TheAbstractFactoryPattern12AbstractFactory的EJB應(yīng)用

EJB容器需要支持多種數(shù)據(jù)庫,每種不同的數(shù)據(jù)庫有相應(yīng)的DataSource。因此容器先根據(jù)部署文件里面的設(shè)置,創(chuàng)建各個(gè)DataSource,然后綁定到其目錄服務(wù)中。使用DataSource的時(shí)候只要從目錄服務(wù)中獲取即可,故其充當(dāng)了DataSource的AbstractFactory。

實(shí)際上,EJB容器將所有資源(JMSFactory、EJBHome等)的Factory全綁定到了目錄服務(wù)中,使用這些Factory的時(shí)候都是由目錄服務(wù)獲取,因此目錄服務(wù)是所有資源Factory的AbstractFactory。AbstractFactory的EJB應(yīng)用13TheSingletonPattern

Singleton模式應(yīng)用在系統(tǒng)中的某些對象有且只能有一個(gè)實(shí)例的情況下,也就是確保類只能實(shí)例化一次。 很多類都是Singleton,例如Java語言里的System、Runtime和Math類,JDBC中的DriverManager等。TheSingletonPattern Sing14Singleton模式的實(shí)現(xiàn)利用StaticClasses來實(shí)現(xiàn)。如Java語言中的System和Math類。結(jié)合Factory模式實(shí)現(xiàn)。由于Factory負(fù)責(zé)對象的創(chuàng)建,在其中實(shí)現(xiàn)Singleton更優(yōu)雅且具彈性。此外,因多數(shù)Factory都要求只有一個(gè)實(shí)例,AbstractFactory的實(shí)現(xiàn)廣泛采用了Singleton模式。Singleton模式的實(shí)現(xiàn)利用StaticClasses15ThePrototypePattern當(dāng)創(chuàng)建對象非常耗費(fèi)資源且復(fù)雜的時(shí)候,為避免重復(fù)對象的創(chuàng)建過程,而采用復(fù)制已有對象的副本(或重用已有對象)再作適當(dāng)更改的方法來加快其創(chuàng)建速度。這便是Prototype模式。

J2EE環(huán)境中,多數(shù)昂貴資源的創(chuàng)建都通過采用實(shí)例緩沖技術(shù)來實(shí)現(xiàn)Prototype模式。典型例子為JDBC的鏈接緩沖池。ThePrototypePattern當(dāng)創(chuàng)16Prototype模式的應(yīng)用Prototype模式對于昂貴的資源來說是非常有價(jià)值的,在J2EE環(huán)境里面得到廣泛的應(yīng)用。其實(shí)現(xiàn)多數(shù)是以實(shí)例緩沖的形式出現(xiàn),且有不少開源項(xiàng)目專注與相關(guān)類庫的開發(fā)。與Singleton模式類似,Prototype模式多數(shù)是結(jié)合Factory使用。如容器中的DataSource就具備鏈接緩沖的功能。Prototype模式的應(yīng)用Prototype17小節(jié)Factory模式用于屏蔽對象的創(chuàng)建邏輯,根據(jù)輸入的數(shù)據(jù)從相似的類中選擇和返回相應(yīng)類的實(shí)例。AbstractFactory模式是用于產(chǎn)生Factory的Factory。Singleton模式可確保系統(tǒng)中的某些類有且只有一個(gè)實(shí)例,并使其能全局訪問。Prototype模式運(yùn)用在創(chuàng)建新對象代價(jià)過高的環(huán)境下,通過重用已有對象達(dá)到節(jié)省資源和提高性能的目的。小節(jié)Factory模式用于屏蔽對象的創(chuàng)建邏輯,根據(jù)輸入的數(shù)據(jù)18StructuralPatternsTheAdapterPatternTheCompositePatternTheDecoratorPatternTheFacadePatternTheProxyPatternStructuralPatternsTheAdapter19TheAdapterPattern

Adapter模式用于轉(zhuǎn)換類的編程接口,將編程接口不同而功能相似的類用一個(gè)統(tǒng)一的接口封裝起來。 顧名思義,Adapter就是起到一個(gè)中轉(zhuǎn)橋梁的作用。其思想也很簡單,編寫一個(gè)實(shí)現(xiàn)了統(tǒng)一接口的類,由其與編程接口相異的類打交道,從而達(dá)到屏蔽類編程細(xì)節(jié)的目的。TheAdapterPattern Adapter模20Adapter模式的實(shí)現(xiàn) Adapter模式的實(shí)現(xiàn)方案通常有兩種:類繼承以需要適配的類為基礎(chǔ),派生一個(gè)子類,然后在子類中添加新的函數(shù),實(shí)現(xiàn)制訂的統(tǒng)一接口。類聯(lián)合創(chuàng)建一個(gè)新的類,其中包含需要適配的類。然后給新類添加函數(shù),實(shí)現(xiàn)制訂的統(tǒng)一接口。Adapter模式的實(shí)現(xiàn) Adapter模式的實(shí)現(xiàn)方案通常有21Adapter模式實(shí)現(xiàn)和應(yīng)用舉例 舉一個(gè)簡單的例子來說明Adapter的應(yīng)用和實(shí)現(xiàn)。下面看到的是一個(gè)簡單的Java程序,將左邊列表中的字符串移到右邊,或者反之。開始程序是用AWT類庫實(shí)現(xiàn)的,而后來我們要將其改為JFC,因兩個(gè)類庫的功能類似,但是調(diào)用接口差異大,所以引入Adapter模式,避免變更波及整個(gè)程序。Adapter模式實(shí)現(xiàn)和應(yīng)用舉例 舉一個(gè)簡單的例子來說明A22示例附圖函數(shù)變更AWTListclassadd(String)remove(String)String[]getSelectedItems()JFCJListclass……Object[]getSelectedValues()示例附圖函數(shù)變更AWTListclassJFCJLis23TheCompositePattern 編程中往往會(huì)遇到一個(gè)組件既可僅為一個(gè)單獨(dú)的對象,也可用對象集合來表示的情況。這便是Composite模式的用武之地。 典型的案例是樹型結(jié)構(gòu)數(shù)據(jù),每個(gè)節(jié)點(diǎn)既可包含多個(gè)子節(jié)點(diǎn),也可能是葉子節(jié)點(diǎn)。且各個(gè)節(jié)點(diǎn)一般是不同的類。 為了將所有節(jié)點(diǎn)組織起來,從所有節(jié)點(diǎn)類中抽象出能表示其共性和樹型結(jié)構(gòu)的接口,這便是Composite。TheCompositePattern 編程中往往會(huì)遇24Composite模式舉例

以上為公司所有職位的結(jié)構(gòu)圖,每個(gè)員工可能有其下屬,也包含了姓名和工資等共有的信息。如何將類組織起來,使其既能表達(dá)樹型結(jié)構(gòu)的組織關(guān)系,又可以表示出員工的共有信息,是Composite模式要解決的問題。Composite模式舉例 以上為公司所有職位的結(jié)構(gòu)圖25Composite模式示例的實(shí)現(xiàn)

綜合樹型結(jié)構(gòu)表示所需函數(shù)以及員工的共有信息可以提取出以下抽象類(或接口):

publicabstractclassEmployee{ publicfloatgetSalary(){...} publicStringgetName(){...} publicfloatgetSalaries(){...} publicabstractintgetTypeCode();

publicabstractbooleanisLeaf(); publicbooleanadd(Employeee){...} publicvoidremove(Employeee){...} publicEmployeegetChild(Strings){...} publicEnumerationelements(){...} } 抽象類Employee的add、remove、getChild和elements體現(xiàn)了樹型數(shù)據(jù)結(jié)構(gòu)的基本操作,其它的屬性為員工的共有信息。然后以之為基類,根據(jù)員工的職能派生出具體的實(shí)現(xiàn)類。Composite模式示例的實(shí)現(xiàn) 綜合樹型結(jié)構(gòu)表示所需函數(shù)26Composite模式應(yīng)用于DOM

XML數(shù)據(jù)同樣也可看成是樹型結(jié)構(gòu),因此XML解釋器將其由字符串轉(zhuǎn)換成一種樹型模型DOM。然后就可以基于DOM對XML進(jìn)行數(shù)據(jù)提取、遍歷及各種編輯操作。

DOM是W3C制訂的標(biāo)準(zhǔn),完全基于Composite模式。其中所有節(jié)點(diǎn)都用Node接口表示,然后由其派生出Element,Text和Attribute等接口。Composite模式應(yīng)用于DOM XML數(shù)據(jù)同樣也可看成27DOM應(yīng)用圖例publicinterfaceNode{ publicStringgetNodeName(); publicshortgetNodeType(); publicStringgetPrefix(); ... publicNodegetParentNode(); publicbooleanhasChildNodes(); publicNodeListgetChildNodes(); publicNodeappendChild(NodenewChild); publicNoderemoveChild(NodeoldChild); publicNodeinsertBefore(NodenewChild,NoderefChild); ...}DOM應(yīng)用圖例publicinterfaceNode{28TheDecoratorPattern

Decorator模式為我們提供了一種無需創(chuàng)建派生類就能改變對象行為的方法。 某個(gè)對象需要改變行為,添加附加的特性,多數(shù)情況下采用類繼承是能夠解決。比如當(dāng)其需要三種不同的附加特性,可以為其創(chuàng)建三個(gè)派生類。但是若它還需要同時(shí)具有其中兩種特性或者是各種特性的任意組合的時(shí)候,類繼承的方法就不再適合了,Decorator模式則為解決之道。TheDecoratorPattern Decorat29Decorator模式的實(shí)現(xiàn) 使用類繼承解決對象行為改變問題時(shí),關(guān)鍵是在派生類中覆蓋需要改變行為的函數(shù)。這實(shí)際上是一種攔截函數(shù)激發(fā)的方法,在函數(shù)激發(fā)前(或后)添加新的動(dòng)作而實(shí)現(xiàn)行為變更。 截獲函數(shù)激發(fā)還可先將欲攔截的函數(shù)提取到一個(gè)基類或接口中。再針對各種動(dòng)作分別實(shí)現(xiàn)相應(yīng)的類。然后通過類的聯(lián)合嵌套就能實(shí)現(xiàn)函數(shù)的攔截。且該方法能由改變類的嵌套來達(dá)到以任何特性的組合改變函數(shù)行為的目的。這便是Decorator模式實(shí)現(xiàn)方案。本質(zhì)上看,這是一種關(guān)于函數(shù)攔截的設(shè)計(jì)模式。Decorator模式的實(shí)現(xiàn) 使用類繼承解決對象行為改變問30Decorator模式用于Java的I/O

Java的I/O系統(tǒng)是完全構(gòu)建在Decorator模式之上的。其使用方法和我們前面介紹的例子是非常相似的。 實(shí)現(xiàn)方面則比示例要復(fù)雜些,接口和抽象類都用上了。 借助Decorator模式,Java的I/O系統(tǒng)非常靈活,且擴(kuò)展性佳。Decorator模式用于Java的I/O Java的I/31Decorator模式用于Servlet

Servlet是用于編寫動(dòng)態(tài)網(wǎng)頁的服務(wù)端組件。容器接收到Http請求后就激活相應(yīng)的Servlet,由其運(yùn)行后輸出結(jié)果返回給客戶端。 在Servlet激發(fā)之前(或后)往往需要執(zhí)行些附加的動(dòng)作,比如顯示廣告、網(wǎng)頁的一些固定標(biāo)題欄等等。于是依據(jù)Decorator模式,引入了Filter。Decorator模式用于Servlet Servlet是32TheFacadePattern 通常隨著代碼的增加,系統(tǒng)變得越來越復(fù)雜,演化出多個(gè)模塊,甚至加入層式設(shè)計(jì)。特別是引入設(shè)計(jì)模式后,類的數(shù)目開始膨脹。這些都會(huì)導(dǎo)致程序的邏輯過于復(fù)雜難懂。

Fa?ade模式提倡將復(fù)雜系統(tǒng)依據(jù)其各模塊(或?qū)樱┑墓δ?,提取出接口,屏蔽掉具體的實(shí)現(xiàn)邏輯,使相互間的調(diào)用明晰簡潔。這既確保了模塊間的隔離性,促進(jìn)模塊保持職責(zé)明晰,也使系統(tǒng)的體系框架保持清晰。TheFacadePattern 通常隨著代碼的增加,33Fa?ade模式與Factory模式 Fa?ade模式用于屏蔽模塊的具體實(shí)現(xiàn),F(xiàn)actory模式則是側(cè)重于屏蔽創(chuàng)建邏輯。這兩個(gè)模式綜合起來后就能使得模塊間做到完全隔離。 兩者結(jié)合的例子非常多,在所有的Java技術(shù)規(guī)范中都有很好的體現(xiàn)。Fa?ade模式與Factory模式 Fa?ade模式用于34Fa?ade模式在J2EE中的應(yīng)用

J2EE程序設(shè)計(jì)中,往往采用層式結(jié)構(gòu),一般分成Web、Service、Domain和Persistence,共四個(gè)層。 層與層之間的調(diào)用遵照Fa?ade模式,完全依靠接口。若是違反該原則,會(huì)造成很多不良影響。特別是涉及到遠(yuǎn)程通訊和事務(wù)的問題時(shí),后果通常非常嚴(yán)重。Fa?ade模式在J2EE中的應(yīng)用 J2EE程序設(shè)計(jì)中,往35TheProxyPattern 當(dāng)需要用簡單的對象來表示一個(gè)復(fù)雜對象的時(shí)候,Proxy模式便可以派上用場。 若是創(chuàng)建對象比較耗時(shí)或消耗資源很多,則可以為其創(chuàng)建一個(gè)Proxy對象,將對象的創(chuàng)建和初始化推遲到真正需要使用其的時(shí)候進(jìn)行。這也是通常所說的惰性載入策略。此外,如對象訪問涉及權(quán)限問題,也可采用Proxy模式。TheProxyPattern 當(dāng)需要用簡單的對象來表36Proxy模式的應(yīng)用EJB是典型的分布式組件,其客戶端全都是通過Proxy對象與之交互的。這樣容器可以從中透明地加入安全、事務(wù)、惰性載入和生存期管理等服務(wù)。JDO使得客戶端能以對象的方式操作數(shù)據(jù)庫的數(shù)據(jù)。實(shí)際上,客戶端訪問的對象全是代理對象,其中實(shí)現(xiàn)了緩沖和惰性載入的功能。Proxy模式的應(yīng)用EJB是典型的分布式組件,其客戶端全37Proxy模式與Fa?ade模式

Proxy模式常常和分布式系統(tǒng)關(guān)聯(lián)在一起,既然涉及物理上分離的系統(tǒng),那么他們之間的交互調(diào)用要有一個(gè)定義良好的接口才行,這就是Facade模式所關(guān)注的問題。因此在引入Proxy模式時(shí),往往必須先將接口進(jìn)行精心設(shè)計(jì),故連帶使用了Facade模式。Proxy模式與Fa?ade模式 Proxy模式常常和分布38BehavioralPatternsChainofResponsibilityTheCommandPatternTheInterpreterPatternTheIteratorPatternTheMediatorPatternTheObserverPatternTheStatePatternTheStrategyPatternTheTemplatePatternTheVisitorPatternBehavioralPatternsChainofRe39ChainofResponsibility ChainofResponsibility模式允許多個(gè)類處理一個(gè)相同的request,卻無需相互知曉,從而為這些類提供了松耦合的結(jié)構(gòu)。 很多系統(tǒng)的request響應(yīng)處理機(jī)制都使用了ChainofResponsibility模式,request沿著響應(yīng)鏈傳遞,直至遇到能處理之的類,如JFC和MFC的消息處理、Servlet的HTTP請求響應(yīng)等。ChainofResponsibility Chain40ChainofResponsibility的實(shí)現(xiàn) 該模式的實(shí)現(xiàn)關(guān)鍵在于響應(yīng)鏈的實(shí)現(xiàn),即是將所有request的處理類串起來形成響應(yīng)鏈。響應(yīng)鏈的操作主要是添加處理類和激發(fā)處理類,用接口表示如下:

publicinterfaceChain{

publicvoidaddChain(Chainc); publicvoidinvoke(Stringmesg);

}

所有的處理類都實(shí)現(xiàn)以上接口,即可組成響應(yīng)鏈。ChainofResponsibility的實(shí)現(xiàn) 該模41程序能根據(jù)輸入的字符串顯示不同的內(nèi)容。實(shí)現(xiàn)舉例響應(yīng)鏈為:SenderImagerColorImageFileListRestList程序能根據(jù)輸入的字符串顯示不同的內(nèi)容。實(shí)現(xiàn)舉例響應(yīng)鏈為:Se42ChainofResponsibility的應(yīng)用

Servlet用于動(dòng)態(tài)響應(yīng)HTTP請求,經(jīng)常遇到將request傳給多個(gè)Servlet的情況,故相關(guān)的設(shè)計(jì)廣泛采用了該模式。 典型例子就是Servlet的Filter,它是Decorator模式與ChainofResponsibility模式的結(jié)合體。ChainofResponsibility的應(yīng)用 Se43TheCommandPattern

Command模式常用于根據(jù)不同request執(zhí)行相應(yīng)處理代碼。其核心思想是將處理代碼分別封裝到不同的具有統(tǒng)一激活接口的類中。這樣可借助數(shù)組或散列等對處理類進(jìn)行管理和優(yōu)化其激發(fā)過程,使request的傳遞與處理代碼分離。且既可將各處理代碼相互隔離,也使得響應(yīng)端對客戶端完全透明。

Command模式的應(yīng)用非常廣泛,J2EE和開源項(xiàng)目中經(jīng)??梢娖渖碛埃⊿ervlet、Struts、JUnit等),它也是Refactor所用到的基礎(chǔ)模式之一。TheCommandPattern Command模式44Command模式實(shí)現(xiàn)舉例 借用ChainofResponsibility模式中的例子,對其進(jìn)行改造使其符合Command模式。 由例子不難看出采用Command模式后,程序的代碼減少,結(jié)構(gòu)得到優(yōu)化,彈性大大增強(qiáng)。 同時(shí)也不難發(fā)現(xiàn)Command模式容易導(dǎo)致類數(shù)量的膨脹。Command模式實(shí)現(xiàn)舉例 借用ChainofResp45Command模式與響應(yīng)鏈

Command模式和響應(yīng)鏈都起到了隔離處理代碼和使響應(yīng)端對客戶端透明的作用。

Command模式簡化和優(yōu)化了request到處理代碼的傳遞,為request的擴(kuò)展提供良好支持。 響應(yīng)鏈只是將傳遞流程以鏈?zhǔn)交驑湫徒Y(jié)構(gòu)管理起來,為處理代碼的激發(fā)順序提供了很好的靈活性。Command模式與響應(yīng)鏈 Command模式和響應(yīng)鏈都起46Command模式的應(yīng)用舉例

Servlet是完全遵照Command模式設(shè)計(jì)的。每個(gè)Servlet都包含兩個(gè)激發(fā)函數(shù)doGet和doPost。激活Servlet的URL或Map則在部署文件里設(shè)定。

JUnit也是以Command模式為基礎(chǔ)的。TestCase需要通過TestSuit以樹型的結(jié)構(gòu)組織起來。這樣就必須將所有TestCase設(shè)計(jì)成具有統(tǒng)一激活接口的類。Command模式的應(yīng)用舉例 Servlet是完全遵照Co47TheInterpreterPattern 某些系統(tǒng)得益于具備專門的語言來描述其所能進(jìn)行的操作,這便是Interpreter模式的用武之地。

定制語言我們經(jīng)常會(huì)接觸到,如VBA、SQL等。解釋器的設(shè)計(jì)可能非常復(fù)雜,要求設(shè)計(jì)人員具備相關(guān)的技能。故描述何時(shí)應(yīng)引入定制語言是Interpreter模式的關(guān)鍵之一。TheInterpreterPattern 某些系統(tǒng)得48何時(shí)引入定制語言程序必須解釋執(zhí)行任意的字符指令程序以字符指令為輸入,根據(jù)指令執(zhí)行不同的動(dòng)作。例如數(shù)學(xué)運(yùn)算和數(shù)理統(tǒng)計(jì)方面的軟件、數(shù)據(jù)庫的DDL等。程序必須產(chǎn)生多種多樣的輸出結(jié)果盡管這些輸出結(jié)果和執(zhí)行流程各異,但它們執(zhí)行所包含的操作步驟卻是相同的。故需要一種語言來描述相關(guān)的操作。如報(bào)表軟件、數(shù)據(jù)庫的DML、轉(zhuǎn)換XML文檔的XSL等。何時(shí)引入定制語言程序必須解釋執(zhí)行任意的字符指令程序以字符指49定制語言和XML

XML是一種元語言,可以基于其上構(gòu)建不同的應(yīng)用語言。由于XML是業(yè)界廣為接受的標(biāo)準(zhǔn),基于其上的語言顯得更加簡明易懂。而且XML的解釋器通用易得,XML的樹型結(jié)構(gòu)又能清晰地表示出語法樹,故為解釋器的實(shí)現(xiàn)提供了不少便利。不少系統(tǒng)的定制語言都采用之,如Ant、Cocoon、Struts、CQL、XQuery等定制語言和XML XML是一種元語言,可以基于其上構(gòu)建不同50TheIteratorPattern Iterator模式簡單而常用,它允許我們通過標(biāo)準(zhǔn)的接口遍歷某個(gè)集合中的數(shù)據(jù)而無需關(guān)心其內(nèi)部的數(shù)據(jù)組織結(jié)構(gòu)。此外,還可以定制特殊的Iterator來過濾返回的數(shù)據(jù)。 在很多涉及數(shù)據(jù)遍歷的場合中都會(huì)用到Iterator,如Java的鏈表、散列等數(shù)據(jù)集合的遍歷,數(shù)據(jù)庫查詢返回的數(shù)據(jù)集遍歷。TheIteratorPattern Iterator51Iterator模式的接口定義

Iterator的接口定義大同小異,可以根據(jù)具體的情況定制。通常情況下,接口定義如下:

publicinterfaceIterator { publicObjectFirst(); publicObjectNext(); publicbooleanhasNext(); publicObjectCurrentItem(); }Iterator模式的接口定義 Iterator的接口定義52Iterator和Composite模式

Composite模式常用于組織樹型結(jié)構(gòu)數(shù)據(jù),故同樣會(huì)面臨數(shù)據(jù)遍歷的問題。樹型數(shù)據(jù)的遍歷主要有兩種不同的算法:深度優(yōu)先和廣度優(yōu)先。利用Iterator,可以將具體的遍歷算法屏蔽,客戶端也就不再受算法的困擾。 此外,Iterator還可用于每個(gè)節(jié)點(diǎn)所包含子節(jié)點(diǎn)的遍歷。Iterator和Composite模式 Composit53Iterator模式實(shí)現(xiàn)舉例 左邊的列表是通過Iterator遍歷所有數(shù)據(jù)并顯示 右邊的列表則采用了包含過濾功能的Iterator,只列出屬于某個(gè)俱樂部的隊(duì)員。Iterator模式實(shí)現(xiàn)舉例 左邊的列表是通過Iterato54TheMediatorpattern 隨著系統(tǒng)功能的增加,更多的類被引入,且相互之間的調(diào)用變得更加復(fù)雜頻繁。類之間因調(diào)用需要知曉對方的函數(shù),然而知道得越多,系統(tǒng)變得越難維護(hù),松耦合的結(jié)構(gòu)會(huì)逐漸被破壞。 為保持系統(tǒng)的松耦合結(jié)構(gòu)引入Mediator模式。Mediator是唯一包含類函數(shù)調(diào)用細(xì)節(jié)的類,其余所有類都是通過它來實(shí)現(xiàn)相互通信,從而隔離各個(gè)類,延續(xù)系統(tǒng)的松耦合結(jié)構(gòu)。TheMediatorpattern 隨著系統(tǒng)功能的增55Mediator實(shí)現(xiàn)舉例從左邊列表選中的文本加入文本框中,同時(shí)Copy按鈕變?yōu)镋nabled。點(diǎn)擊Copy按鈕,文本加入到右邊列表,且Clear按鈕Enabled。點(diǎn)擊Clear后,文本框和右列表被清空,Copy和Clear按鈕重新變成Disabled。Mediator實(shí)現(xiàn)舉例從左邊列表選中的文本加入文本框中,同56示例中的組件調(diào)用關(guān)系

從圖中可見原先系統(tǒng)各組件存在著復(fù)雜的調(diào)用關(guān)系。采用Mediator模式后,涉及組件間功能調(diào)用的代碼全部集中到了Mediator,故組件間的關(guān)系變得簡明,系統(tǒng)保持了松耦合結(jié)構(gòu)。示例中的組件調(diào)用關(guān)系 從圖中可見原先系統(tǒng)各組件存在著復(fù)雜的調(diào)57Mediator、Factory和Facade 系統(tǒng)通常采用分而治之的策略劃分成多個(gè)模塊。模塊的結(jié)構(gòu)設(shè)計(jì)主要面臨三方面的問題:模塊間的通信模塊內(nèi)各類的相互調(diào)用創(chuàng)建和初始化管理 結(jié)合Mediator、Factory和Fa?ade,可設(shè)計(jì)出結(jié)構(gòu)優(yōu)雅規(guī)范的模塊。Mediator、Factory和Facade 系統(tǒng)通常采58TheObserverPattern 在很多系統(tǒng)中都會(huì)遇到需要同時(shí)將數(shù)據(jù)以不同的形式顯示出來,且顯示要能及時(shí)反應(yīng)出數(shù)據(jù)的變更。 傳統(tǒng)的做法經(jīng)常將數(shù)據(jù)邏輯和表示邏輯混和在一起。隨著數(shù)據(jù)表現(xiàn)形式的增加,系統(tǒng)會(huì)陷入煩雜而難以維護(hù)的境地。解決該問題需要引入Observer模式。將數(shù)據(jù)和表現(xiàn)形式徹底隔離,為表現(xiàn)形式的多樣化提供最大的彈性。 TheObserverPattern 在很多系統(tǒng)中都會(huì)59Observer模式的原理

Observer模式將數(shù)據(jù)邏輯(Subject)及其表現(xiàn)邏輯(Observers)完全分離,分別封裝到不同的類中。

當(dāng)數(shù)據(jù)變更時(shí)會(huì)通知Observers刷新,用戶只需通過Subject來操作數(shù)據(jù),Observers對其完全透明。因此添加新的Observers不會(huì)對其它部分有影響。Observer模式的原理 Observer模式將數(shù)據(jù)邏60Observer模式的實(shí)現(xiàn)

由原理不難看出Observer模式的實(shí)現(xiàn)關(guān)鍵在于Subject和Observers間的協(xié)同工作。為了響應(yīng)數(shù)據(jù)變更,Observers需要實(shí)現(xiàn)接口:

abstractinterfaceObserver{ publicvoidsendNotify(數(shù)據(jù)變更); } 然后Observers將其注冊到Subject,數(shù)據(jù)變換時(shí)由其調(diào)用接口的sendNotify通知Observers刷新。顯然,Subject需要實(shí)現(xiàn)以下接口來接受注冊。 abstractinterfaceSubject{ publicvoidregisterInterest(Observerobs); }Observer模式的實(shí)現(xiàn) 由原理不難看出Observer61實(shí)現(xiàn)舉例 例子帶有一個(gè)Subject(底下的窗口)和兩個(gè)Observes(上面的兩個(gè)窗口)。Subject中的選擇改變時(shí),Color窗口會(huì)變色,列表窗體則隨之選中不同的項(xiàng)。實(shí)現(xiàn)舉例 例子帶有一個(gè)Subject(底下的窗口)和兩個(gè)O62Observer模式與MVC

MVC(Model-View-Controller)的核心思想和Observer模式是完全類似的。數(shù)據(jù)模型(業(yè)務(wù)邏輯)和表現(xiàn)邏輯相互隔離,Controller則負(fù)責(zé)與客戶交互,根據(jù)請求調(diào)用M和V的功能。 通常情況下Controller并不單獨(dú)存在,而是和M或V結(jié)合(JFC中便是如此)。但在分布式系統(tǒng)中,客戶端不可能直接與M或V進(jìn)行交互,此時(shí)Controller將獨(dú)立出來并發(fā)揮重要作用。訪問協(xié)議、請求分發(fā)、安全認(rèn)證、日志記錄和異常處理等都由其承擔(dān)。Observer模式與MVC MVC(Model-Vie63Struts-MVC的成功典范

MVC在Web程序開發(fā)中獲得廣泛應(yīng)用,由此也誕生了很多MVC的框架,其中的成功典范當(dāng)屬Struts。其工作流程如右圖:

Struts將重點(diǎn)放在Controller,實(shí)現(xiàn)了請求解釋和數(shù)據(jù)校驗(yàn)、請求分發(fā)、聲明型異常處理和頁面跳轉(zhuǎn)等特性。Struts-MVC的成功典范 MVC在Web程序開發(fā)中獲64TheStatepattern 復(fù)雜的程序往往有許多狀態(tài),不同狀態(tài)下的行為相異。如何使得系統(tǒng)隨著狀態(tài)增加而仍然保持邏輯清晰是State模式所解決的問題。 已往遇到該問題的時(shí)候通常都是使用大量的if-else或switch語句來判斷應(yīng)該采取何種行為。這種方法容易使系統(tǒng)陷入邏輯含糊不清的境地,State模式則可幫助系統(tǒng)以簡潔的方式工作于不同狀態(tài)。TheStatepattern 復(fù)雜的程序往往有許多狀65State模式舉例

講解State模式原理之前先看一個(gè)類似畫筆的繪圖程序。 窗口ToolBar的按鈕分別對應(yīng)功能:選擇、畫矩形、填充、畫圓和清除。State模式舉例 講解State模式原理之前先看一個(gè)類似66示例程序的設(shè)計(jì)思路

程序設(shè)計(jì)的難題在于按下ToolBar的不同按鈕時(shí)要采取相應(yīng)的行為。但是不難發(fā)現(xiàn)狀態(tài)不同的代碼差異主要集中在窗體的mouseDown、mouseUp和mouseDrag事件的響應(yīng)函數(shù)。由此可提出基類:

publicclassState{ publicvoidmouseDown(intx,inty){} publicvoidmouseUp(intx,inty){} publicvoidmouseDrag(intx,inty){} }

然后針對不同的狀態(tài)為該接口寫子類,并創(chuàng)建StateMana

ger管理之,負(fù)責(zé)狀態(tài)的維護(hù)。這樣窗體mouse事件的響應(yīng)代碼只需和StateManager打交道,與各狀態(tài)的執(zhí)行代碼完全隔離。示例程序的設(shè)計(jì)思路 程序設(shè)計(jì)的難題在于按下ToolBar的67State模式的原理 狀態(tài)的差異通常只是引起程序某些方面的行為不同,故可以將存在差別的地方分別用函數(shù)概括總結(jié)出來,再把這些函數(shù)集中形成接口或者虛類。然后針對不同的狀態(tài)來分別編寫其實(shí)現(xiàn),并創(chuàng)建StateManager來管理之。 這樣程序只需要通過StateManager來工作,將不同狀態(tài)的處理代碼與之隔離開來,因此變得簡潔易懂。系統(tǒng)的彈性和可維護(hù)性都得到很大提升。State模式的原理 狀態(tài)的差異通常只是引起程序某些方面的68TheStrategyPattern 系統(tǒng)的某些操作存在多種算法的時(shí)候,如何將這些算法組織起來,保持代碼的簡明清晰是Strategy模式所解決的問題。 Strategy模式的核心思想與State是類似的。將需要使用不同算法的各個(gè)部分用函數(shù)概括出來,集中提取成基類。然后就可以針對不同的算法寫實(shí)現(xiàn)。同樣還需Context類把這些類管理起來。TheStrategyPattern 系統(tǒng)的某些操作69Strategy模式實(shí)現(xiàn)舉例 讀取數(shù)據(jù),并以不同的算法將其顯示出來Strategy模式實(shí)現(xiàn)舉例 讀取數(shù)據(jù),并以不同的算法將其顯70Strategy模式與State模式

兩個(gè)模式很相似,核心思想是基本一致的,其差別主要源于各自的應(yīng)用范圍不同。Strategy的Context只是實(shí)例化指定的算法類。而State的StateManager初始化時(shí)會(huì)創(chuàng)建所有狀態(tài)的處理類。

Strategy中封裝的算法,從某個(gè)角度看都是在做相同的事情,而State的不同狀態(tài)執(zhí)行的是完全不同的操作。

State中會(huì)頻繁出現(xiàn)狀態(tài)切換跳轉(zhuǎn)的情況,但是Strategy則不然。Strategy模式與State模式 兩個(gè)模式很相似,核心71TheTemplatePattern 當(dāng)我們創(chuàng)建一個(gè)基類,將其中某些方法留給子類實(shí)現(xiàn),實(shí)際上就使用了Template模式。該模式的實(shí)現(xiàn)方法非常簡單,只要定義基類(往往是虛類)再在子類中覆蓋實(shí)現(xiàn)其父類某些函數(shù)即可。 盡管Template模式的實(shí)現(xiàn)很簡單,但是其思想是相當(dāng)重要的,對代碼重用和體系結(jié)構(gòu)優(yōu)化有著重要意義。此外,它也是Refactor最常用的模式之一。The

溫馨提示

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

評論

0/150

提交評論