




已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
二十三種設(shè)計模式1 引言談到設(shè)計模式,絕對應(yīng)該一起來說說重構(gòu)。重構(gòu)給我們帶來了什么?除了作為對遺留代碼的改進(jìn)的方法,另一 大意義在于,可以讓我們在寫程序的時候可以不需事先考慮太多的代碼組織問題,當(dāng)然這其中也包括了應(yīng)用模式的問題。盡管大多數(shù)開發(fā)者都已經(jīng)養(yǎng)成了寫代碼前先 從設(shè)計開始的習(xí)慣,但是,這種程度的設(shè)計,涉及到到大局、到總體架構(gòu)、到主要的模塊劃分我覺得就夠了。換句話說,這時就能寫代碼了。這就得益于重構(gòu)的思想 了。如果沒有重構(gòu)的思想,有希望獲得非常高質(zhì)量的代碼,我們就不得不在開始寫代碼前考慮更多其實并非非常穩(wěn)定的代碼組織及設(shè)計模式的應(yīng)用問題,那開發(fā)效率 當(dāng)然就大打折扣了。在重構(gòu)和設(shè)計模式的合理應(yīng)用之下,我們可以相對較早的開始寫代碼,并在功能盡早實現(xiàn)的同時,不斷地通過重構(gòu)和模式來改善我們的代碼質(zhì) 量。所以,下面的章節(jié)中,在談模式的同時,我也會談?wù)勱P(guān)于常用的這些模式的重構(gòu)成本的理解。重構(gòu)成本越高意味著,在遇到類似的問題情形的時候,我們更應(yīng)該 提前考慮應(yīng)用對應(yīng)的設(shè)計模式,而重構(gòu)成本比較低則說明,類似的情形下,完全可以先怎么方便,怎么快怎么寫,哪怕代碼不是很優(yōu)雅也沒關(guān)系,回頭再重構(gòu)也很容 易。1 創(chuàng)建型1.1 Factory Method思想:Factory Method的主要思想是使一個類的實例化延遲到其子類。場景:典 型的應(yīng)用場景如:在某個系統(tǒng)開發(fā)的較早階段,有某些類的實例化過程,實例化方式可能還不是很確定,或者實際實例化的對象(可能是需要對象的某個子類中的一 個)不確定,或者比較容易變化。此時,如果直接將實例化過程寫在某個函數(shù)中,那么一般就是if-else或select-case代 碼。如果,候選項的數(shù)目較少、類型基本確定,那么這樣的if-else還是可以接受的,一旦情形變 得復(fù)雜、不確定性增加,更甚至包含這個構(gòu)造過程的函數(shù)所在的類包含幾個甚至更多類似的函數(shù)時,這樣的if-else代 碼就會變得比較不那么容易維護(hù)了。此時,應(yīng)用本模式,可以將這種復(fù)雜情形隔離開,即將這類不確定的對象的實例化過程延遲到子類。實現(xiàn):該模式的典型實現(xiàn)方法就是將調(diào)用類定義為一個虛類,在調(diào)用類定義一個專門用于構(gòu)造不確定的對象實例的虛函數(shù),再將實際的對象實例化代碼 留到調(diào)用類的子類來實現(xiàn)。如果,被構(gòu)造的對象比較復(fù)雜的話,同時可以將這個對象定義為可以繼承、甚至虛類,再在不同的調(diào)用類的子類中按需返回被構(gòu)造類的子 類。重構(gòu)成本:低。該模式的重構(gòu)成本實際上還與調(diào)用類自己的實例化方式相關(guān)。如果調(diào)用類是通過Factory方 式(此處“Factory方式”泛指對象的實例化通過Factory Method或Abstract Factory這樣的相對獨立出來的 方式構(gòu)造)構(gòu)造的,那么,重構(gòu)成本相對就會更低。否則,重構(gòu)時可能除了增加調(diào)用類的子類,還要將所有實例化調(diào)用類的地方,修改為以新增的子類代替??赡苓@ 樣的子類還不止一個,那就可以考慮迭代應(yīng)用模式來改善調(diào)用類的實例化代碼。1.2 Abstract Factory思想:不直接通過對象的具體實現(xiàn)類,而是通過使用專門的類來負(fù)責(zé)一組相關(guān)聯(lián)的對象的創(chuàng)建。場景:最典型的應(yīng)用場景是:您只想暴露對象的接口而不想暴露具體的實現(xiàn)類,但是又想提供實例化對象的接口給用戶;或者,您希望所有的對象能夠 集中在一個或一組類(通常稱作工廠類)來創(chuàng)建,從而可以更方便的對對象的實例化過程進(jìn)行動態(tài)配置(此時只需要修改工廠類的代碼或配置)。實現(xiàn):該模式的實現(xiàn)是比較清晰簡單的,如上圖,就是定義創(chuàng)建和返回各種類對象實例的工廠類。在最復(fù)雜而靈活的情形,無論工廠類本身還是被創(chuàng)建 的對象類都可能需要有一個繼承體系。簡單情形其實可以只是一個工廠類和需要被創(chuàng)建的對象類。不一定非要像上圖中結(jié)構(gòu)那么完備(累贅)。重構(gòu)成本:中。如果一開始所有的對象都是直接創(chuàng)建,例如通過new實例化的, 而之后想重構(gòu)為Abstract Factory模式,那么,很自然的我們需要替換所有直接的new實 例化代碼為對工廠類對象創(chuàng)建方法的調(diào)用??紤]到像Resharper這樣的重構(gòu)工具的支持,找出對 某個方法或構(gòu)造函數(shù)的調(diào)用位置這樣的操作相對還是比較容易,重構(gòu)成本也不是非常高。同時,重構(gòu)成本還和被創(chuàng)建對象的構(gòu)造函數(shù)的重載數(shù)量相關(guān)。您需要根據(jù)實 際情況考慮,是否工廠類要映射被創(chuàng)建對象的所有重載版本的構(gòu)造函數(shù)。1.3 Builder思想:將一個類的創(chuàng)建過程和他的主體部分分離。場景:該模式的典型的應(yīng)用場景是:一個類的創(chuàng)建過程可能比較復(fù)雜,或者創(chuàng)建過程中的某些階段可能會容易變化;或者多個類的創(chuàng)建過程比較類似, 但是主體不同。實現(xiàn):在 以上提到的兩種場景中,我們就可以取出一個類的創(chuàng)建過程的代碼,定義一個專門的Builder類, 而在原來創(chuàng)建類對象實例的地方,將這個Builder類的實例作為參數(shù)傳入。還有第二個重點,就是Builder類 可以將將整個創(chuàng)建過程分為幾個階段,每個階段不必在類中直接實現(xiàn),而可以通過繼承體系在子類中實現(xiàn),或者通過子類的方法過載來修改創(chuàng)建過程中的某個階段, 但是重用其他的階段??梢园l(fā)現(xiàn),該模式將一個對象的復(fù)雜創(chuàng)建過程重用到非常高的層次。這正是它的意義所在。重構(gòu)成本:低。該模式的重構(gòu)成本我覺得是非常低的,因為一般來講,創(chuàng)建過程的代碼本來也就應(yīng)該在原來的類的構(gòu)造函數(shù)中,把它Extract出 來就好了。如果發(fā)現(xiàn)多個類的創(chuàng)建過程有比較多的代碼重復(fù)或類似,那么就可以重用這些提取出來的Builder類 或者Builder類中的某些階段。1.4 Prototype思想:克 隆一個已有的類的實例(大家相比都用過甚至寫過類的Clone實現(xiàn),應(yīng)該很容易理解了)。場景:應(yīng) 用Clone的場景應(yīng)該說非常多,理想情況下我當(dāng)然希望任何類都能Clone, 需要的時候就能Clone一份一模一樣的出來。實現(xiàn):這 里將的實現(xiàn)主要之實現(xiàn)的表現(xiàn)形式,而不是如何用具體的語言來實現(xiàn)。因此,只要為需要Clone能力 的類定義一個Clone方法就行。當(dāng)然,一般,主流的程序語言框架都已經(jīng)定義了通用的Clone接 口(當(dāng)然也可以自己定義),繼承并實現(xiàn)該接口和方法就好。重構(gòu)成本:極低。不多解釋了吧。1.5 Singleton思想:保證一個類只有一個唯一的實例。場景:生活中有些對象就是只要一個就好了,我們的代碼中為什么要每次都為這樣的對象生成一個實例呢?實現(xiàn):最 簡單的實現(xiàn)方式就是使用一個static型的類實例,每次對該對象的創(chuàng)建請求都返回這個static的 唯一實例就行。重構(gòu)成本:極低。2 結(jié)構(gòu)型2.1 Adapter思想:將一個類的接口轉(zhuǎn)換成另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。場景:該 模式的應(yīng)用場景太多了,很多需要的功能模塊的接口和我們需要的不完全一致或者有多余或不足,但是需要和我們的系統(tǒng)協(xié)同工作,通過Adapter把 它包裝一下就能讓使它接口兼容了。實現(xiàn):定 義一個Adapter類,包含需要包裝的類,實現(xiàn)需要的其它接口,調(diào)用被包裝的類的方法來實現(xiàn)需要 的接口。重構(gòu)成本:低。2.2 Bridge思想:將一個類的抽象定義和具體實現(xiàn)解耦。場景:該 模式的典型應(yīng)用場景是:一個類的抽象定義已經(jīng)確定,但是,其實現(xiàn)代碼甚至原理可能會不同。比如:我們最熟悉的圖形界面中的window的 實現(xiàn),無論在什么操作系統(tǒng),什么平臺的機(jī)器上,一個window應(yīng)具有的抽象定義基本上是一致的, 但是,其實現(xiàn)代碼肯定會因為平臺不同,機(jī)器的代碼指令不同而不同。此時,如果希望您寫的window類 能跨平臺,應(yīng)用Bridge模式就是一個好主意。實現(xiàn):該 模式的實現(xiàn)方法很簡單,就是除了定義類的抽象定義之外,將一個類的所有實現(xiàn)代碼獨立出一個實現(xiàn)類。這樣一來,無論是抽象定義還是實現(xiàn)類都能分別修改和重 用,但只要兩部分的交互接口不變,還是可以方便的互相組裝。當(dāng)然,實際上也沒有必要隔離出“所有實現(xiàn)代碼”,只需要隔離需要的部分就行了。因此,也可以 說,從代碼結(jié)構(gòu)來看,Builder模式是一種變種的Bridge模 式的。也經(jīng)常有人將Bridge模式和接口相比較,如果隔離出所有的實現(xiàn),那么的確接口的方式也能 做到抽象定義和實現(xiàn)分離,但是,Bridge有其優(yōu)勢如下:一、究竟隔離多少代碼到Bridge類 中可以靈活確定,二、減少了總的類的數(shù)目,三、允許被隔離出來的Bridge類被其它的類直接共享 使用。重構(gòu)成本:中。將所有的(或很大部分)實現(xiàn)代碼分離開來總還是一件不大,但是,也不小的事。所以標(biāo)個“中”在這里。:)2.3 Composite思想:將 對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對單個對象和組合對象的使用具有一致 性。場景:該 模式的應(yīng)用場景極其類似,比如像圖形系統(tǒng),如電路設(shè)計、UML建模系統(tǒng),或者像web的 顯示元素等,都是那種需要整體和部分具有使用接口上的一定的一致性的需求的結(jié)構(gòu),實際上,我覺得這樣的系統(tǒng)如果不使用Composite模 式將會是慘不忍睹的。實現(xiàn):該模式的實現(xiàn)主要就是要表示整體或部分的所有類都繼承自同一的基類或接口,從而擁有使用接口上一定的一致性。重構(gòu)成本:高。2.4 Decorator思想:為一個對象已有的子類添加一些額外的職責(zé)。場景:該模式的使用場景,主要是有的時候我們不愿意定義邏輯上新的子類,因為沒有新的邏輯含義上的子類概念,而只是想為一個已存在的子類附加 一些職責(zé)。實現(xiàn):該 模式的實現(xiàn)主要就是定義一個物理上的新的子類,但是,它只是包含要附加職責(zé)的類,傳遞外部對相同接口的調(diào)用,在這個傳遞調(diào)用的通道上附加額外的功能。突然 想到,Decorator模式是不是一定程度上也能代替DynamicProxy模 式,從而成為一種AOP實現(xiàn)的方案呢?重構(gòu)成本:低。定義一個Decorator和一個已有類的邏輯上的子類,物理 表現(xiàn)形式上都是一個子類,重構(gòu)也確實不是難事。2.5 Facade思想:為子系統(tǒng)中的一組接口提供一個一致的界面,這個接口使得這一子系統(tǒng)更加容易使用。場景:當(dāng) 你要為一個復(fù)雜子系統(tǒng)提供一個簡單接口時。子系統(tǒng)往往因為不斷演化而變得越來越復(fù)雜。大多數(shù)模式使用時都會產(chǎn)生更多更小的類。這使得子系統(tǒng)更具可重用性, 也更容易對子系統(tǒng)進(jìn)行定制,但這也給那些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難。Facade可 以提供一個簡單的缺省視圖,這一視圖對大多數(shù)用戶來說已經(jīng)足夠,而那些需要更多的可定制性的用戶可以越過Facade層。 客戶程序與抽象類的實現(xiàn)部分之間存在著很大的依賴性。引入Facade將這個子系統(tǒng)與客戶以及其他 的子系統(tǒng)分離,可以提高子系統(tǒng)的獨立性和可移植性。當(dāng)你需要構(gòu)建一個層次結(jié)構(gòu)的子系統(tǒng)時,使用Facade模 式定義子系統(tǒng)中每層的入口點。如果子系統(tǒng)之間是相互依賴的,你可以讓它們僅通過Facade進(jìn)行通 訊,從而簡化了它們之間的依賴關(guān)系。(這里直接引用了設(shè)計模式迷你手冊,因為覺得它確實已經(jīng)說得很明了了,下面類似的情形我直接引用原文的就不再注明 了,這里先說明一下,感謝手冊作者的這些優(yōu)秀總結(jié)。當(dāng)然,本文的絕大多數(shù)文字都是Teddy本 人的原創(chuàng)看法,絕非抄襲,您可以比較本文和附件手冊,附件同時也會提供本文的Word版本下 載。)實現(xiàn):該 模式的實現(xiàn)需要定義一個新的系統(tǒng)構(gòu)架上的Layer,該層向上提供一組新的接口,向下調(diào)用子系統(tǒng)原 有的接口。重構(gòu)成本:高。要修改所有直接對子系統(tǒng)的地調(diào)用為對Faade層的調(diào)用還是 有很多事情要做的。不過,現(xiàn)代IDE中,如果我們刪除調(diào)用層對子系統(tǒng)的程序集引用,那么所有這些我 們需要修改的調(diào)用都能標(biāo)示出來,因為編譯不能通過了嘛,因此,重構(gòu)的風(fēng)險還不算特別大,只是工作量著實不小。2.6 Flyweight思想:說Flyweight可 能有的朋友第一次看到想象不到是什么樣子,其實說他就是一個Pool,你可能就明白了。也就是由一 個Flyweight Factory來管理一族一定數(shù)目邏輯上經(jīng)常需要構(gòu)建和銷毀的細(xì)顆粒對象, 例如我們常見的數(shù)據(jù)庫連接池。在Factory內(nèi)部,并不物理銷毀這些對象,而在接到實例化請求時 返回這些被關(guān)系對象的實例,從而減少創(chuàng)建銷毀這些細(xì)顆粒對象的開銷。場景:基 本上所有的需要Pool這個概念的環(huán)境都能應(yīng)用。實現(xiàn):實現(xiàn)的底層方式可以千變?nèi)f化,在接口上就是如上圖所示,花樣不多。這里就不多解釋。重構(gòu)成本:低。2.7 Proxy思想:前 面在Decorator模式中也提到了Proxy模 式了。它是通過邏輯上繼承一個已有類的子類,從而擴(kuò)展原有的子類的功能。場景:需 要注意體會他和Decorator的需別。Proxy是 繼承需要修飾的類,而Decorator用的是包含的方式。Proxy模 式,或者準(zhǔn)確地說DynamicProxy模式,是現(xiàn)代AOP框 架實現(xiàn)中的一種常用方式。典型的實現(xiàn)如Spring,JBoss以 及Castle Project中的Aspect#。實現(xiàn):繼承,并在過載方法中添加需要的修飾功能。重構(gòu)成本:低。3 行為型3.1 Interpreter思想:當(dāng) 有一個語言需要解釋執(zhí)行, 并且你可將該語言中的句子表示為一個抽象語法樹時,定義一個解釋器,這 個解釋器使用該表示來解釋語言中的句子。場景:其 實,從物理結(jié)構(gòu)上,該模式的代碼架構(gòu)看起來可能和Composite模式一模一樣,致使其針對的邏 輯語義不同。Composite模式描述一種一般的整體和部分使用接口上的一致性,而Interpreter模 式則側(cè)重于語言解釋器的實現(xiàn)構(gòu)架。實現(xiàn):如 上圖,基本同Composite模式。重構(gòu)成本:高。3.2 Iterator思想:提 供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內(nèi)部表示。場景:訪 問一個聚合對象的內(nèi)容而無需暴露它的內(nèi)部表示。支持對聚合對象的多種遍歷。為遍歷不同的聚合結(jié)構(gòu)提供一個統(tǒng)一的接口(即, 支持多態(tài)迭代)。實現(xiàn):其 實就是定義一個邏輯上類似一個指針的迭代類。專門用于這種迭代工作。如果對C+ STL火鍋功夫 學(xué)習(xí)的朋友一定不會陌生啦。實際使用過一下就明白了。除了功能之外,他給我最大的感受就是他讓我熟悉的for(int i = 0; i list.Count; i+)語句,變長了好多。-重構(gòu)成本:中。3.3 Mediator思想:用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。場景:該模式主要用來進(jìn)行降低一組相互關(guān)聯(lián)調(diào)用的對象間的耦合度。如果您發(fā)現(xiàn)您的系統(tǒng)的某部分的一組對象間調(diào)用極其頻繁的壞味道的話,可能您 需要考慮使用該模式來進(jìn)行一些解耦,否則,這些對象中的任何一個的修改,都將可能導(dǎo)致其他對象許多地方的修改,可維護(hù)性就降低了。實現(xiàn):定義一個專門的中介對象來封裝和傳遞一組對象間的調(diào)用。重構(gòu)成本:中。3.4 Memento思想:用在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復(fù)到原先保存的狀態(tài)。場景:該 模式主要用來實現(xiàn)類似我們在常見的編輯器中經(jīng)常執(zhí)行的Undo(Ctrl+Z) 操作。實際上就是在外部保持一組對象的某一時刻的狀態(tài),并在需要的另一個時候?qū)⑦@組對象回復(fù)到之前的狀態(tài)。實現(xiàn):該 模式其實主要是一種對象狀態(tài)的暫存和回復(fù)的思想。上面的UML圖是一種比較典型的實現(xiàn)方式定一 個專門用于保存類狀態(tài)的類,為被保存狀態(tài)的類定義返回當(dāng)前狀態(tài)類實例,和根據(jù)狀態(tài)類實例回復(fù)對象狀態(tài)的接口。實際上也不必太拘泥于這個實現(xiàn),簡單情形下, 我們完全可以利用任何的已有的對象持久化或者序列化機(jī)制來用一個字符串暫存對象的當(dāng)前完整狀態(tài)。重構(gòu)成本:低。3.5 Template Method思想:定 義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使 得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。場景:該 模式實際上是一種非常直觀和可理解的OO思想下的代碼重用的實現(xiàn)。只需一次性實現(xiàn)一個算法的不變的 部分,并將可變的行為留給子類來實現(xiàn)。各子類中公共的行為應(yīng)被提取出來并集中到一個公共父類中以避免代碼重復(fù)。模板方法只允許在特定點計算法的某個階段被 過載,這樣也就只允許在這些點進(jìn)行擴(kuò)展。實現(xiàn):見上圖,太簡單了,就不多說了。重構(gòu)成本:低。3.6 Chain of Responsibility思想:使多個對象都有機(jī)會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一 個對象處理它為止。場景:該模式實際上是對人們常會不自覺地去做的一種代碼組織方式的總結(jié)而已。有的時候一條消息需要被處理,我們當(dāng)然可以在一個雷的一個方法中 對他進(jìn)行所有需要的處理。但是,如果要做的處理很復(fù)雜的情形,甚至能夠按照一定的邏輯醒來分類所有這些處理,則不要在一個雷一個函數(shù)里處以一切會更好,我 們可以定義多個處理類類表示邏輯上的不同的處理,然后一個個處理類的傳遞這個消息對象,讓希望處理該消息的類自己決定是不是要處理。這樣,就能將一個難以 維護(hù)的復(fù)雜處理過程,分解為一系列簡單明了,易于維護(hù)的類了。實現(xiàn):上圖是實現(xiàn)方式之一。即,使所有可能處理該請求的對象繼承自一個基類,實際上,只要邏輯語義上我們保持這樣一種讓每個處理類自己決定何 時處理,并傳遞請求的思想,實現(xiàn)方式也可以千變?nèi)f化,無論是用接口代替,或者甚至只是簡單的定義相同結(jié)構(gòu)的處理函數(shù)而通過反射機(jī)制來調(diào)用處理函數(shù)和傳遞處 理請求,都是可選的方案。重構(gòu)成本:中。3.7 Command思想:將一個動態(tài)的執(zhí)行過程封裝成一個對象,可以像處理數(shù)據(jù)來處理和管理這樣的對象,在需要的時候激發(fā)該對象的方法就能執(zhí)行被封裝的執(zhí)行過 程。場景:該模式在很多時候非常有用,它使得我們對邏輯上已經(jīng)激發(fā)的行為進(jìn)行優(yōu)化成為可能,我們不僅可以根據(jù)需要改變一組邏輯上以經(jīng)濟(jì)法的活動的 順序,消冗余操作,撤銷不必要的操作等。也可以把活動和操作視為資源一樣來管理和重用。同時該模式也是許多事務(wù)處理機(jī)制的基礎(chǔ)。實現(xiàn):實現(xiàn)很簡單,只是定義一些能夠通過指定接口被激發(fā)的對活動進(jìn)行封裝的類,然后我們按照需要管理這些類,并在需要的時候激發(fā)這些活動。您 還是應(yīng)該更多地去體會,為什么他是事務(wù)處理機(jī)制的基礎(chǔ),當(dāng)我們可以這樣來管理一組活動的時候,可以對這些活動進(jìn)行那些有趣的控制。重構(gòu)成本:高。3.8 Observer思想:定 義對象間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時, 所 有依賴于它的對象都得到通知并被自動更新。場景:上面描述該模式思想的文字可能顯得有些拗口,實際上你也不用想得過于復(fù)雜。只要你寫過任何的基于圖形界面的程序,那么實際上您對他是一 點也不該陌生的。它就是我們每一次鼠標(biāo)鍵盤敲擊都在我們的程序內(nèi)部流轉(zhuǎn)著的事件機(jī)制的基礎(chǔ)。當(dāng)一個事件發(fā)生,則通知訂閱該事件的對象。實現(xiàn):上 面的UML圖看似復(fù)雜,實際上,去理解它的最好的辦法就是試著思考和使用任何一種OO語 言來定義一個擁有事件機(jī)制的類。比如,.Net下,你只要好好去看看關(guān)于delegate的 文檔,嘗試著根據(jù)MSDN寫寫看一個最簡單的自定義事件。那么,上面的UML圖, 我敢保證你能很輕易的看明白。重構(gòu)成本:高。3.9 State思想:允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為。場景:實 際上該模式在作為重構(gòu)的目的是,絕大多數(shù)情況我們做的事情是將對一個類的state進(jìn)行if-else或 者select-case,決定該執(zhí)行什么操作的過程解耦的過程。實現(xiàn):將 表述一個類的某些操作該做什么,該怎么做的信息保存到其state中。即用一個包含更多信息,甚至 執(zhí)行邏輯的state類實例來代替一個簡單數(shù)據(jù)類型的state屬 性。重構(gòu)成本:中。3.10 Strategy思想:定 義一系列的算法,把它們一個個封裝起來, 并 且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。場景:該 模式實際上也可以理解為一種Bridge模式的變種。只是它突出的是,一般當(dāng)我們把一個類或者一組 類的一些代碼獨立成一個Strategy類的時候,我們可能會為同樣接口的這些算法定義多個接口一 致,但是實現(xiàn)方法不同的版本,并在需要的時候靈活的替換這些算法。實現(xiàn):實 現(xiàn)方式同Bridge模式。重構(gòu)成本:中。3.11 Visitor思想:表 示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。場景:其 實你不用去理解上面這句話。該模式其實又是一個在代碼的物理結(jié)構(gòu)上和Bridge模式很相似的模 式。但是,其語義,其目的,在邏輯上又是不同的。如果說Bridge,以及上述我稱為可視為Bridge擴(kuò) 展的模式中,作為參數(shù)的Bridge類,是作為調(diào)用類的被訪問對象的話,Visitor, 在大多數(shù)情形下,如其英文含義,它在語義上是完全相反的。不是他被調(diào)用的類處理,更大程度上它處于主動狀態(tài),是它去訪問,去處理調(diào)用它的類。調(diào)用它的類, 把自己對別人隱藏起來的東西,暴露給Visitor品嘗,任君蹂躪(這個,這個千 萬別想歪了;-)。另一方面,即使邏輯上沒有這種Visitor主 動去訪問調(diào)用類的語義,只要Visitor類中的操作,是依賴于調(diào)用類的具體實現(xiàn)類(它本身或他某 個層次的子類)的某些狀態(tài)或者方法的,那么,就可以應(yīng)用該模式來分離出這樣的可重用的操作。實現(xiàn):類 似Bridge模式。重構(gòu)成本:中。二十三種設(shè)計模式介紹設(shè)計模式主要分三個類型:創(chuàng)建型、結(jié)構(gòu)型和行為型。 其中創(chuàng)建型有: 一、Singleton,單例模式:保證一個類只有一個實例,并提供一個訪問它的全局訪問點 二、Abstract Factory,抽象工廠:提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無須指定它們的具體類。 三、Factory Method,工廠方法:定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類,F(xiàn)actory Method使 一個類的實例化延遲到了子類。 四、Builder,建造模式:將一個復(fù)雜對象的構(gòu)建與他的表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 五、Prototype,原型模式:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型來創(chuàng)建新的對象。 行為型有: 六、Iterator,迭代器模式:提供一個方法順序訪問一個聚合對象的各個元素,而又不需要暴露該對象的內(nèi)部表示。 七、Observer,觀察者模式:定義對象間一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知自動更新。 八、Template Method,模板方法:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中,TemplateMethod 使得子類可以不改變一個算法的結(jié)構(gòu)即可以重定義該算法得某些特定步驟。 九、Command,命令模式:將一個請求封裝為一個對象,從而使你可以用不同的請求對客戶進(jìn)行參數(shù)化,對請求排隊和記錄請求日志,以及 支持可撤銷的操作。 十、State,狀態(tài)模式:允許對象在其內(nèi)部狀態(tài)改變時改變他的行為。對象看起來似乎改變了他的類。 十一、Strategy,策略模式:定義一系列的算法,把他們一個個封裝起來,并使他們可以互相替換,本模式使得算法可以獨立于使用它們 的客戶。 十二、China of Responsibility,職責(zé)鏈模式:使多個對象都有機(jī)會處理請求,從而避免請求的送發(fā)者和接收者之間的 耦合關(guān)系 十三、Mediator,中介者模式:用一個中介對象封裝一些列的對象交互。 十四、Visitor,訪問者模式:表示一個作用于某對象結(jié)構(gòu)中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用于這個元素 的新操作。 十五、Interpreter,解釋器模式:給定一個語言,定義他的文法的一個表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言 中的句子。 十六、Memento,備忘錄模式:在不破壞對象的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。 結(jié)構(gòu)型有: 十七、Composite,組合模式:將對象組合成樹形結(jié)構(gòu)以表示部分整體的關(guān)系,Composite使得用戶對單個對象和組合對象的使 用具有一致性。 十八、Facade,外觀模式:為子系統(tǒng)中的一組接口提供一致的界面,fa?ade提供了一高層接口,這個接口使得子系統(tǒng)更容易使用。 十九、Proxy,代理模式:為其他對象提供一種代理以控制對這個對象的訪問 二十、Adapter,適配器模式:將一類的接口轉(zhuǎn)換成客戶希望的另外一個接口,Adapter模式使得原本由于接口不兼容而不能一起工 作那些類可以一起工作。 二十一、Decrator,裝飾模式:動態(tài)地給一個對象增加一些額外的職責(zé),就增加的功能來說,Decorator模式相比生成子類更加 靈活。 二十二、Bridge,橋模式:將抽象部分與它的實現(xiàn)部分相分離,使他們可以獨立的變化。 二十三、Flyweight,享元模式:二十三種設(shè)計模式通俗理解這幾天接觸到了設(shè)計模式,就查了一些關(guān)于這方面的資料,覺得還不錯,所以就拿出來與大家一起分享了。1、FACTORY 追MM少不了請吃飯了,麥當(dāng)勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當(dāng)勞或肯德基,只管向服務(wù)員說“來四個雞翅”就行了。麥當(dāng)勞和肯德基就是生產(chǎn)雞翅的Factory 工廠模式:客戶類和工廠類分開。消費者任何時候需要某種產(chǎn)品,只需向工廠請求即可。消費者無須修改就可以接納新產(chǎn)品。缺點是當(dāng)產(chǎn)品修改時,工廠類也要做相應(yīng)的修改。如:如何創(chuàng)建及如何向客戶端提供。2、BUILDER MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機(jī),上面每種語言都有一個按鍵,見到 MM我只要按對應(yīng)的鍵,它就能夠用相應(yīng)的語言說出“我愛你”這句話了,國外的MM也可以輕松搞掂,這就是我的“我愛你”builder。(這一定比美軍在伊拉克用的翻譯機(jī)好賣) 建造模式:將產(chǎn)品的內(nèi)部表象和產(chǎn)品的生成過程分割開來,從而使一個建造過程生成具有不同的內(nèi)部表象的產(chǎn)品對象。建造模式使得產(chǎn)品內(nèi)部表象可以獨立的變化,客戶不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié)。建造模式可以強(qiáng)制實行一種分步驟進(jìn)行的建造過程。3、FACTORY METHOD 請MM去麥當(dāng)勞吃漢堡,不同的MM有不同的口味,要每個都記住是一件煩人的事情,我一般采用Factory Method模式,帶著MM到服務(wù)員那兒,說“要一個漢堡”,具體要什么樣的漢堡呢,讓MM直接跟服務(wù)員說就行了。 工廠方法模式:核心工廠類不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建的工作交給子類去做,成為一個抽象工廠角色,僅負(fù)責(zé)給出具體工廠類必須實現(xiàn)的接口,而不接觸哪一個產(chǎn)品類應(yīng)當(dāng)被實例化這種細(xì)節(jié)。4、PROTOTYPE 跟MM用QQ聊天,一定要說些深情的話語了,我搜集了好多肉麻的情話,需要時只要copy出來放到QQ里面就行了,這就是我的情話prototype 了。(100塊錢一份,你要不要) 原始模型模式:通過給出一個原型對象來指明所要創(chuàng)建的對象的類型,然后用復(fù)制這個原型對象的方法創(chuàng)建出更多同類型的對象。原始模型模式允許動態(tài)的增加或減少產(chǎn)品類,產(chǎn)品類不需要非得有任何事先確定的等級結(jié)構(gòu),原始模型模式適用于任何的等級結(jié)構(gòu)。缺點是每一個類都必須配備一個克隆方法。5、SINGLETON 俺有6個漂亮的老婆,她們的老公都是我,我就是我們家里的老公Sigleton,她們只要說道“老公”,都是指的同一個人,那就是我(剛才做了個夢啦,哪有這么好的事) 單例模式:單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例單例模式。單例模式只應(yīng)在有真正的“單一實例”的需求時才可使用。 b:9ceca65206結(jié)構(gòu)型模式/b:9ceca652066、ADAPTER 在朋友聚會上碰到了一個美女Sarah,從香港來的,可我不會說粵語,她不會說普通話,只好求助于我的朋友kent了,他作為我和Sarah之間的 Adapter,讓我和Sarah可以相互交談了(也不知道他會不會耍我) 適配器(變壓器)模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口原因不匹配而無法一起工作的兩個類能夠一起工作。適配類可以根據(jù)參數(shù)返還一個合適的實例給客戶端。7、BRIDGE 早上碰到MM,要說早上好,晚上碰到MM,要說晚上好;碰到MM穿了件新衣服,要說你的衣服好漂亮哦,碰到MM新做的發(fā)型,要說你的頭發(fā)好漂亮哦。不要問我“早上碰到MM新做了個發(fā)型怎么說”這種問題,自己用BRIDGE組合一下不就行了 橋梁模式:將抽象化與實現(xiàn)化脫耦,使得二者可以獨立的變化,也就是說將他們之間的強(qiáng)關(guān)聯(lián)變成弱關(guān)聯(lián),也就是指在一個軟件系統(tǒng)的抽象化和實現(xiàn)化之間使用組合 /聚合關(guān)系而不是繼承關(guān)系,從而使兩者可以獨立的變化。8、COMPOSITE Mary今天過生日。“我過生日,你要送我一件禮物。”“嗯,好吧,去商店,你自己挑。”“這件T恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買?!?“喂,買了三件了呀,我只答應(yīng)送一件禮物的哦?!薄笆裁囱?,T恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來?!薄啊?,MM都會用 Composite模式了,你會了沒有? 合成模式:合成模式將對象組織到樹結(jié)構(gòu)中,可以用來描述整體與部分的關(guān)系。合成模式就是一個處理對象的樹結(jié)構(gòu)的模式。合成模式把部分與整體的關(guān)系用樹結(jié)構(gòu)表示出來。合成模式使得客戶端把一個個單獨的成分對象和由他們復(fù)合而成的合成對象同等看待。9、DECORATOR Mary過完輪到Sarly過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我去年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術(shù)設(shè)計的Mike設(shè)計了一個漂亮的盒子裝起來,我們都是 Decorator,最終都在修飾我這個人呀,怎么樣,看懂了嗎? 裝飾模式:裝飾模式以對客戶端透明的方式擴(kuò)展對象的功能,是繼承關(guān)系的一個替代方案,提供比繼承更多的靈活性。動態(tài)給一個對象增加功能,這些功能可以再動態(tài)的撤消。增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能。10、FACADE 我有一個專業(yè)的Nikon相機(jī),我就喜歡自己手動調(diào)光圈、快門,這樣照出來的照片才專業(yè),但MM可不懂這些,教了半天也不會。幸好相機(jī)有Facade設(shè)計模式,把相機(jī)調(diào)整到自動檔,只要對準(zhǔn)目標(biāo)按快門就行了,一切由相機(jī)自動調(diào)整,這樣MM也可以用這個相機(jī)給我拍張照片了。 門面模式:外部與一個子系統(tǒng)的通信必須通過一個統(tǒng)一的門面對象進(jìn)行。門面模式提供一個高層次的接口,使得子系統(tǒng)更易于使用。每一個子系統(tǒng)只有一個門面類,而且此門面類只有一個實例,也就是說它是一個單例模式。但整個系統(tǒng)可以有多個門面類。11、FLYWEIGHT 每天跟MM發(fā)短信,手指都累死了,最近買了個新手機(jī),可以把一些常用的句子存在手機(jī)里,要用的時候,直接拿出來,在前面加上MM的名字就可以發(fā)送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特征,根據(jù)上下文情況使用。 享元模式:FLYWEIGHT在拳擊比賽中指最輕量級。享元模式以共享的方式高效的支持大量的細(xì)粒度對象。享元模式能做到共享的關(guān)鍵是區(qū)分內(nèi)蘊(yùn)狀態(tài)和外蘊(yùn)狀態(tài)。內(nèi)蘊(yùn)狀態(tài)存儲在享元內(nèi)部,不會隨環(huán)境的改變而有所不同。外蘊(yùn)狀態(tài)是隨環(huán)境的改變而改變的。外蘊(yùn)狀態(tài)不能影響內(nèi)蘊(yùn)狀態(tài),它們是相互獨立的。將可以共享的狀態(tài)和不可以共享的狀態(tài)從常規(guī)類中區(qū)分開來,將不可以共享的狀態(tài)從類里剔除出去??蛻舳瞬豢梢灾苯觿?chuàng)建被共享的對象,而應(yīng)當(dāng)使用一個工廠對象負(fù)責(zé)創(chuàng)建被共享的對象。享元模式大幅度的降低內(nèi)存中對象的數(shù)量。12、PROXY 跟MM在網(wǎng)上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程序做為我的Proxy吧,凡是接收到這些話都設(shè)置好了自己的回答,接收到其他的話時再通知我回答,怎么樣,酷吧。 代理模式:代理模式給某一個對象提供一個代理對象,并由代理對象控制對源對象的引用。代理就是一個人或一個機(jī)構(gòu)代表另一個人或者一個機(jī)構(gòu)采取行動。某些情況下,客戶不想或者不能夠直接引用一個對象,代理對象可以在客戶和目標(biāo)對象直接起到中介的作用??蛻舳朔直娌怀龃碇黝}對象與真實主題對象。代理模式可以并不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創(chuàng)建被代理對象,被代理對象必須有系統(tǒng)的其他角色代為創(chuàng)建并傳入。 b:9ceca65206行為模式/b:9ceca6520613、CHAIN OF RESPONSIBLEITY 晚上去上英語課,為了好開溜坐到了最后一排,哇,前面坐了好幾個漂亮的MM哎,找張紙條,寫上“Hi,可以做我的女朋友嗎?如果不愿意請向前傳”,紙條就一個接一個的傳上去了,糟糕,傳到第一排的MM把紙條傳給老師了,聽說是個老處女呀,快跑! 責(zé)任鏈模式:在責(zé)任鏈模式中,很多對象由每一個對象對其下家的引用而接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求??蛻舨⒉恢梨溕系哪囊粋€對象最終處理這個請求,系統(tǒng)可以在不影響客戶端的情況下動態(tài)的重新組織鏈和分配責(zé)任。處理者有兩個選擇:承擔(dān)責(zé)任或者把責(zé)任推給下家。一個請求可以最終不被任何接收端對象所接受。14、COMMAND 俺有一個MM家里管得特別嚴(yán),沒法見面,只好借助于她弟弟在我們倆之間傳送信息,她對我有什么指示,就寫一張紙條讓她弟弟帶給我。這不,她弟弟又傳送過來一個COMMAND,為了感謝他,我請他吃了碗雜醬面,哪知道他說:“我同時給我姐姐三個男朋友送COMMAND,就數(shù)你最小氣,才請我吃面?!保?命令模式:命令模式把一個請求或者操作封裝到一個對象中。命令模式把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開,委派給不同的對象。命令模式允許請求的一方和發(fā)送的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否執(zhí)行,何時被執(zhí)行以及是怎么被執(zhí)行的。系統(tǒng)支持命令的撤消。15、INTERPRETER 俺有一個泡MM真經(jīng),上面有各種泡MM的攻略,比如說去吃西餐的步驟、去看電影的方法等等,跟MM約會時,只要做一個Interpreter,照著上面的腳本執(zhí)行就可以了。 解釋器模式:給定一個語言后,解釋器模式可以定義出其文法的一種表示,并同時提供一個解釋器??蛻舳丝梢允褂眠@個解釋器來解釋這個語言中的句子。解釋器模式將描述怎樣在有了一個簡單的文法后,使用模式設(shè)計解釋這些語句。在解釋器模式里面提到的語言是指任何解釋器對象能夠解釋的任何組合。在解釋器模式中需要定義一個代表文法的命令類的等級結(jié)構(gòu),也就是一系列的組合規(guī)則。每一個命令對象都有一個解釋方法,代表對命令對象的解釋。命令對象的等級結(jié)構(gòu)中的對象的任何排列組合都是一個語言。16、ITERATOR 我愛上了Mary,不顧一切的向她求婚。 Mary:“想要我跟你結(jié)婚,得答應(yīng)我的條件” 我:“什么條件我都答應(yīng),你說吧” Mary:“我看上了那個一克拉的鉆石” 我:“我買,我買,還有嗎?” Mary:“我看上了湖邊的那棟別墅” 我:“我買,我買,還有嗎?” Mary:“我看上那輛法拉利跑車” 我腦袋嗡的一聲,坐在椅子上,一咬牙:“我買,我買,還有嗎?” 迭代子模式:迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內(nèi)部表象。多個對象聚在一起形成的總體稱之為聚集,聚集對象是能夠包容一組對象的容器對象。迭代子模式將迭代邏輯封裝到一個獨立的子對象中,從而與聚集本身隔開。迭代子模式簡化了聚集的界面。每一個聚集對象都可以有一個或一個以上的迭代子對象,每一個迭代子的迭代狀態(tài)可以是彼此獨立的。迭代算法可以獨立于聚集角色變化。17、MEDIATOR 四個MM打麻將,相互之間誰應(yīng)該給誰多少錢算不清楚了,幸虧當(dāng)時我在旁邊,按照各自的籌碼數(shù)算錢,賺了錢的從我這里拿,賠了錢的也付給我,一切就OK啦,俺得到了四個MM的電話。 調(diào)停者模式:調(diào)停者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用。從而使他們可以松散偶合。當(dāng)某些對象之間的作用發(fā)生改變時,不會立即影響其他的一些對象之間的作用。保證這些作用可以彼此獨立的變化。調(diào)停者模式將多對多的相互作用轉(zhuǎn)化為一對多的相互作用。調(diào)停者模式將對象的行為和協(xié)作抽象化,把對象在小尺度的行為上與其他對象的相互作用分開處理。18、MEMENTO 同時跟幾個MM聊天時,一定要記清楚剛才跟MM說了些什么話,不然MM發(fā)現(xiàn)了會
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 智慧城市基礎(chǔ)設(shè)施的智能化升級實踐
- 四川省瀘州市龍馬潭區(qū)金龍中學(xué)2024年數(shù)學(xué)八上期末達(dá)標(biāo)檢測試題含解析
- 四川省宜賓市翠屏區(qū)二片區(qū)2024-2025學(xué)年物理八上期末質(zhì)量檢測試題含解析
- 銷售團(tuán)隊管理與激勵方案
- 2025年公安院校招警考試題庫(附答案)
- 服裝品牌策劃與市場推廣策略
- 零售業(yè)數(shù)字化轉(zhuǎn)型與創(chuàng)新營銷策略研究
- 2025至2030智能酒店系統(tǒng)行業(yè)發(fā)展趨勢分析與未來投資戰(zhàn)略咨詢研究報告
- 寵物主題解謎挑戰(zhàn)賽熱 門場景設(shè)計研究
- 2025至2030中國自然修護(hù)面膜行業(yè)深度調(diào)研及市場需求與投資報告
- 大疆在線測評題
- 045.糖尿病患者血脂管理中國專家共識2024版
- DB3402T 19-2021 汽車后市場 美容養(yǎng)護(hù)服務(wù)規(guī)范
- 化工公司安全知識競賽題庫(共1000題)
- 中國移動公開競聘考試題庫(含答案)
- DLT 572-2021 電力變壓器運行規(guī)程
- HJ 636-2012 水質(zhì) 總氮的測定 堿性過硫酸鉀消解紫外分光光度法
- 成都市2022級(2025屆)高中畢業(yè)班摸底測試(零診)數(shù)學(xué)試卷(含答案)
- 社會主義核心價值觀融入幼兒園班級管理課程教學(xué)探索
- 四年級下冊混合計算400題及答案
- 餐廳值班管理培訓(xùn)
評論
0/150
提交評論