一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

重讀GoF

 燮羽 2010-11-16
這幾天整理自己的電腦,翻出以前載的一本電子書——RedSword軟件工作室制作的《設(shè)計(jì)模式迷你手冊》,忍不住拿來重讀一遍,也檢驗(yàn)一下自己目前對(duì)這些常用模式的理解。本文算是這次溫故的手記了。

0 引言

談到設(shè)計(jì)模式,絕對(duì)應(yīng)該一起來說說重構(gòu)。重構(gòu)給我們帶來了什么?除了作為對(duì)遺留代碼的改進(jìn)的方法,另一大意義在于,可以讓我們在寫程序的時(shí)候可以不需事先考慮太多的代碼組織問題,當(dāng)然這其中也包括了應(yīng)用模式的問題。盡管大多數(shù)開發(fā)者都已經(jīng)養(yǎng)成了寫代碼前先從設(shè)計(jì)開始的習(xí)慣,但是,這種程度的設(shè)計(jì),涉及到到大局、到總體架構(gòu)、到主要的模塊劃分我覺得就夠了。換句話說,這時(shí)就能寫代碼了。這就得益于重構(gòu)的思想了。如果沒有重構(gòu)的思想,有希望獲得非常高質(zhì)量的代碼,我們就不得不在開始寫代碼前考慮更多其實(shí)并非非常穩(wěn)定的代碼組織及設(shè)計(jì)模式的應(yīng)用問題,那開發(fā)效率當(dāng)然就大打折扣了。在重構(gòu)和設(shè)計(jì)模式的合理應(yīng)用之下,我們可以相對(duì)較早的開始寫代碼,并在功能盡早實(shí)現(xiàn)的同時(shí),不斷地通過重構(gòu)和模式來改善我們的代碼質(zhì)量。所以,下面的章節(jié)中,在談模式的同時(shí),我也會(huì)談?wù)勱P(guān)于常用的這些模式的重構(gòu)成本的理解。重構(gòu)成本越高意味著,在遇到類似的問題情形的時(shí)候,我們更應(yīng)該提前考慮應(yīng)用對(duì)應(yīng)的設(shè)計(jì)模式,而重構(gòu)成本比較低則說明,類似的情形下,完全可以先怎么方便,怎么快怎么寫,哪怕代碼不是很優(yōu)雅也沒關(guān)系,回頭再重構(gòu)也很容易。

1 創(chuàng)建型

1.1 Factory Method

 


思想:

Factory Method的主要思想是使一個(gè)類的實(shí)例化延遲到其子類。

場景:

典型的應(yīng)用場景如:在某個(gè)系統(tǒng)開發(fā)的較早階段,有某些類的實(shí)例化過程,實(shí)例化方式可能還不是很確定,或者實(shí)際實(shí)例化的對(duì)象(可能是需要對(duì)象的某個(gè)子類中的一個(gè))不確定,或者比較容易變化。此時(shí),如果直接將實(shí)例化過程寫在某個(gè)函數(shù)中,那么一般就是if-elseselect-case代碼。如果,候選項(xiàng)的數(shù)目較少、類型基本確定,那么這樣的if-else還是可以接受的,一旦情形變得復(fù)雜、不確定性增加,更甚至包含這個(gè)構(gòu)造過程的函數(shù)所在的類包含幾個(gè)甚至更多類似的函數(shù)時(shí),這樣的if-else代碼就會(huì)變得比較不那么容易維護(hù)了。此時(shí),應(yīng)用本模式,可以將這種復(fù)雜情形隔離開,即將這類不確定的對(duì)象的實(shí)例化過程延遲到子類。

實(shí)現(xiàn):

該模式的典型實(shí)現(xiàn)方法就是將調(diào)用類定義為一個(gè)虛類,在調(diào)用類定義一個(gè)專門用于構(gòu)造不確定的對(duì)象實(shí)例的虛函數(shù),再將實(shí)際的對(duì)象實(shí)例化代碼留到調(diào)用類的子類來實(shí)現(xiàn)。如果,被構(gòu)造的對(duì)象比較復(fù)雜的話,同時(shí)可以將這個(gè)對(duì)象定義為可以繼承、甚至虛類,再在不同的調(diào)用類的子類中按需返回被構(gòu)造類的子類。

重構(gòu)成本:

低。該模式的重構(gòu)成本實(shí)際上還與調(diào)用類自己的實(shí)例化方式相關(guān)。如果調(diào)用類是通過Factory方式(此處“Factory方式”泛指對(duì)象的實(shí)例化通過Factory MethodAbstract Factory這樣的相對(duì)獨(dú)立出來的方式構(gòu)造)構(gòu)造的,那么,重構(gòu)成本相對(duì)就會(huì)更低。否則,重構(gòu)時(shí)可能除了增加調(diào)用類的子類,還要將所有實(shí)例化調(diào)用類的地方,修改為以新增的子類代替。可能這樣的子類還不止一個(gè),那就可以考慮迭代應(yīng)用模式來改善調(diào)用類的實(shí)例化代碼。

1.2 Abstract Factory

 


思想:

不直接通過對(duì)象的具體實(shí)現(xiàn)類,而是通過使用專門的類來負(fù)責(zé)一組相關(guān)聯(lián)的對(duì)象的創(chuàng)建。

場景:

最典型的應(yīng)用場景是:您只想暴露對(duì)象的接口而不想暴露具體的實(shí)現(xiàn)類,但是又想提供實(shí)例化對(duì)象的接口給用戶;或者,您希望所有的對(duì)象能夠集中在一個(gè)或一組類(通常稱作工廠類)來創(chuàng)建,從而可以更方便的對(duì)對(duì)象的實(shí)例化過程進(jìn)行動(dòng)態(tài)配置(此時(shí)只需要修改工廠類的代碼或配置)。

實(shí)現(xiàn):

該模式的實(shí)現(xiàn)是比較清晰簡單的,如上圖,就是定義創(chuàng)建和返回各種類對(duì)象實(shí)例的工廠類。在最復(fù)雜而靈活的情形,無論工廠類本身還是被創(chuàng)建的對(duì)象類都可能需要有一個(gè)繼承體系。簡單情形其實(shí)可以只是一個(gè)工廠類和需要被創(chuàng)建的對(duì)象類。不一定非要像上圖中結(jié)構(gòu)那么完備(累贅)。

重構(gòu)成本:

中。如果一開始所有的對(duì)象都是直接創(chuàng)建,例如通過new實(shí)例化的,而之后想重構(gòu)為Abstract Factory模式,那么,很自然的我們需要替換所有直接的new實(shí)例化代碼為對(duì)工廠類對(duì)象創(chuàng)建方法的調(diào)用??紤]到像Resharper這樣的重構(gòu)工具的支持,找出對(duì)某個(gè)方法或構(gòu)造函數(shù)的調(diào)用位置這樣的操作相對(duì)還是比較容易,重構(gòu)成本也不是非常高。同時(shí),重構(gòu)成本還和被創(chuàng)建對(duì)象的構(gòu)造函數(shù)的重載數(shù)量相關(guān)。您需要根據(jù)實(shí)際情況考慮,是否工廠類要映射被創(chuàng)建對(duì)象的所有重載版本的構(gòu)造函數(shù)。

1.3 Builder

 


思想:

將一個(gè)類的創(chuàng)建過程和他的主體部分分離。

場景:

該模式的典型的應(yīng)用場景是:一個(gè)類的創(chuàng)建過程可能比較復(fù)雜,或者創(chuàng)建過程中的某些階段可能會(huì)容易變化;或者多個(gè)類的創(chuàng)建過程比較類似,但是主體不同。

實(shí)現(xiàn):

在以上提到的兩種場景中,我們就可以取出一個(gè)類的創(chuàng)建過程的代碼,定義一個(gè)專門的Builder類,而在原來創(chuàng)建類對(duì)象實(shí)例的地方,將這個(gè)Builder類的實(shí)例作為參數(shù)傳入。還有第二個(gè)重點(diǎn),就是Builder類可以將將整個(gè)創(chuàng)建過程分為幾個(gè)階段,每個(gè)階段不必在類中直接實(shí)現(xiàn),而可以通過繼承體系在子類中實(shí)現(xiàn),或者通過子類的方法過載來修改創(chuàng)建過程中的某個(gè)階段,但是重用其他的階段??梢园l(fā)現(xiàn),該模式將一個(gè)對(duì)象的復(fù)雜創(chuàng)建過程重用到非常高的層次。這正是它的意義所在。

重構(gòu)成本:

低。該模式的重構(gòu)成本我覺得是非常低的,因?yàn)橐话銇碇v,創(chuàng)建過程的代碼本來也就應(yīng)該在原來的類的構(gòu)造函數(shù)中,把它Extract出來就好了。如果發(fā)現(xiàn)多個(gè)類的創(chuàng)建過程有比較多的代碼重復(fù)或類似,那么就可以重用這些提取出來的Builder類或者Builder類中的某些階段。

1.4 Prototype

 


思想:

克隆一個(gè)已有的類的實(shí)例(大家相比都用過甚至寫過類的Clone實(shí)現(xiàn),應(yīng)該很容易理解了)。

場景:

應(yīng)用Clone的場景應(yīng)該說非常多,理想情況下我當(dāng)然希望任何類都能Clone,需要的時(shí)候就能Clone一份一模一樣的出來。

實(shí)現(xiàn):

這里將的實(shí)現(xiàn)主要之實(shí)現(xiàn)的表現(xiàn)形式,而不是如何用具體的語言來實(shí)現(xiàn)。因此,只要為需要Clone能力的類定義一個(gè)Clone方法就行。當(dāng)然,一般,主流的程序語言框架都已經(jīng)定義了通用的Clone接口(當(dāng)然也可以自己定義),繼承并實(shí)現(xiàn)該接口和方法就好。

重構(gòu)成本:

極低。不多解釋了吧。

1.5 Singleton

 


思想:

保證一個(gè)類只有一個(gè)唯一的實(shí)例。

場景:

生活中有些對(duì)象就是只要一個(gè)就好了,我們的代碼中為什么要每次都為這樣的對(duì)象生成一個(gè)實(shí)例呢?

實(shí)現(xiàn):

最簡單的實(shí)現(xiàn)方式就是使用一個(gè)static型的類實(shí)例,每次對(duì)該對(duì)象的創(chuàng)建請求都返回這個(gè)static的唯一實(shí)例就行。

重構(gòu)成本:

極低。

2 結(jié)構(gòu)型

2.1 Adapter

 


思想:

將一個(gè)類的接口轉(zhuǎn)換成另外一個(gè)接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。

場景:

該模式的應(yīng)用場景太多了,很多需要的功能模塊的接口和我們需要的不完全一致或者有多余或不足,但是需要和我們的系統(tǒng)協(xié)同工作,通過Adapter把它包裝一下就能讓使它接口兼容了。

實(shí)現(xiàn):

定義一個(gè)Adapter類,包含需要包裝的類,實(shí)現(xiàn)需要的其它接口,調(diào)用被包裝的類的方法來實(shí)現(xiàn)需要的接口。

重構(gòu)成本:

低。

2.2 Bridge

 


思想:

將一個(gè)類的抽象定義和具體實(shí)現(xiàn)解耦。

場景:

該模式的典型應(yīng)用場景是:一個(gè)類的抽象定義已經(jīng)確定,但是,其實(shí)現(xiàn)代碼甚至原理可能會(huì)不同。比如:我們最熟悉的圖形界面中的window的實(shí)現(xiàn),無論在什么操作系統(tǒng),什么平臺(tái)的機(jī)器上,一個(gè)window應(yīng)具有的抽象定義基本上是一致的,但是,其實(shí)現(xiàn)代碼肯定會(huì)因?yàn)槠脚_(tái)不同,機(jī)器的代碼指令不同而不同。此時(shí),如果希望您寫的window類能跨平臺(tái),應(yīng)用Bridge模式就是一個(gè)好主意。

實(shí)現(xiàn):

該模式的實(shí)現(xiàn)方法很簡單,就是除了定義類的抽象定義之外,將一個(gè)類的所有實(shí)現(xiàn)代碼獨(dú)立出一個(gè)實(shí)現(xiàn)類。這樣一來,無論是抽象定義還是實(shí)現(xiàn)類都能分別修改和重用,但只要兩部分的交互接口不變,還是可以方便的互相組裝。當(dāng)然,實(shí)際上也沒有必要隔離出“所有實(shí)現(xiàn)代碼”,只需要隔離需要的部分就行了。因此,也可以說,從代碼結(jié)構(gòu)來看,Builder模式是一種變種的Bridge模式的。也經(jīng)常有人將Bridge模式和接口相比較,如果隔離出所有的實(shí)現(xiàn),那么的確接口的方式也能做到抽象定義和實(shí)現(xiàn)分離,但是,Bridge有其優(yōu)勢如下:一、究竟隔離多少代碼到Bridge類中可以靈活確定,二、減少了總的類的數(shù)目,三、允許被隔離出來的Bridge類被其它的類直接共享使用。

重構(gòu)成本:

中。將所有的(或很大部分)實(shí)現(xiàn)代碼分離開來總還是一件不大,但是,也不小的事。所以標(biāo)個(gè)“中”在這里。:)

2.3 Composite

 


思想:

將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

場景:

該模式的應(yīng)用場景極其類似,比如像圖形系統(tǒng),如電路設(shè)計(jì)、UML建模系統(tǒng),或者像web的顯示元素等,都是那種需要整體和部分具有使用接口上的一定的一致性的需求的結(jié)構(gòu),實(shí)際上,我覺得這樣的系統(tǒng)如果不使用Composite模式將會(huì)是慘不忍睹的。

實(shí)現(xiàn):

該模式的實(shí)現(xiàn)主要就是要表示整體或部分的所有類都繼承自同一的基類或接口,從而擁有使用接口上一定的一致性。

重構(gòu)成本:

高。

2.4 Decorator

 


思想:

為一個(gè)對(duì)象已有的子類添加一些額外的職責(zé)。

場景:

該模式的使用場景,主要是有的時(shí)候我們不愿意定義邏輯上新的子類,因?yàn)闆]有新的邏輯含義上的子類概念,而只是想為一個(gè)已存在的子類附加一些職責(zé)。

實(shí)現(xiàn):

該模式的實(shí)現(xiàn)主要就是定義一個(gè)物理上的新的子類,但是,它只是包含要附加職責(zé)的類,傳遞外部對(duì)相同接口的調(diào)用,在這個(gè)傳遞調(diào)用的通道上附加額外的功能。突然想到,Decorator模式是不是一定程度上也能代替DynamicProxy模式,從而成為一種AOP實(shí)現(xiàn)的方案呢?

重構(gòu)成本:

低。定義一個(gè)Decorator和一個(gè)已有類的邏輯上的子類,物理表現(xiàn)形式上都是一個(gè)子類,重構(gòu)也確實(shí)不是難事。

2.5 Facade

 


思想:

為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,這個(gè)接口使得這一子系統(tǒng)更加容易使用。

場景:

當(dāng)你要為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡單接口時(shí)。子系統(tǒng)往往因?yàn)椴粩嘌莼兊迷絹碓綇?fù)雜。大多數(shù)模式使用時(shí)都會(huì)產(chǎn)生更多更小的類。這使得子系統(tǒng)更具可重用性,也更容易對(duì)子系統(tǒng)進(jìn)行定制,但這也給那些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難。Facade可以提供一個(gè)簡單的缺省視圖,這一視圖對(duì)大多數(shù)用戶來說已經(jīng)足夠,而那些需要更多的可定制性的用戶可以越過Facade層??蛻舫绦蚺c抽象類的實(shí)現(xiàn)部分之間存在著很大的依賴性。引入Facade將這個(gè)子系統(tǒng)與客戶以及其他的子系統(tǒng)分離,可以提高子系統(tǒng)的獨(dú)立性和可移植性。當(dāng)你需要構(gòu)建一個(gè)層次結(jié)構(gòu)的子系統(tǒng)時(shí),使用Facade模式定義子系統(tǒng)中每層的入口點(diǎn)。如果子系統(tǒng)之間是相互依賴的,你可以讓它們僅通過Facade進(jìn)行通訊,從而簡化了它們之間的依賴關(guān)系。(這里直接引用了《設(shè)計(jì)模式迷你手冊》,因?yàn)橛X得它確實(shí)已經(jīng)說得很明了了,下面類似的情形我直接引用原文的就不再注明了,這里先說明一下,感謝《手冊》作者的這些優(yōu)秀總結(jié)。當(dāng)然,本文的絕大多數(shù)文字都是Teddy本人的原創(chuàng)看法,絕非抄襲,您可以比較本文和附件《手冊》,附件同時(shí)也會(huì)提供本文的Word版本下載。)

實(shí)現(xiàn):

該模式的實(shí)現(xiàn)需要定義一個(gè)新的系統(tǒng)構(gòu)架上的Layer,該層向上提供一組新的接口,向下調(diào)用子系統(tǒng)原有的接口。

重構(gòu)成本:

高。要修改所有直接對(duì)子系統(tǒng)的地調(diào)用為對(duì)Façade層的調(diào)用還是有很多事情要做的。不過,現(xiàn)代IDE中,如果我們刪除調(diào)用層對(duì)子系統(tǒng)的程序集引用,那么所有這些我們需要修改的調(diào)用都能標(biāo)示出來,因?yàn)榫幾g不能通過了嘛,因此,重構(gòu)的風(fēng)險(xiǎn)還不算特別大,只是工作量著實(shí)不小。

2.6 Flyweight

 


思想:

Flyweight可能有的朋友第一次看到想象不到是什么樣子,其實(shí)說他就是一個(gè)Pool,你可能就明白了。也就是由一個(gè)Flyweight Factory來管理一族一定數(shù)目邏輯上經(jīng)常需要構(gòu)建和銷毀的細(xì)顆粒對(duì)象,例如我們常見的數(shù)據(jù)庫連接池。在Factory內(nèi)部,并不物理銷毀這些對(duì)象,而在接到實(shí)例化請求時(shí)返回這些被關(guān)系對(duì)象的實(shí)例,從而減少創(chuàng)建銷毀這些細(xì)顆粒對(duì)象的開銷。

場景:

基本上所有的需要Pool這個(gè)概念的環(huán)境都能應(yīng)用。

實(shí)現(xiàn):

實(shí)現(xiàn)的底層方式可以千變?nèi)f化,在接口上就是如上圖所示,花樣不多。這里就不多解釋。

重構(gòu)成本:

低。

2.7 Proxy

 


思想:

前面在Decorator模式中也提到了Proxy模式了。它是通過邏輯上繼承一個(gè)已有類的子類,從而擴(kuò)展原有的子類的功能。

場景:

需要注意體會(huì)他和Decorator的需別。Proxy是繼承需要修飾的類,而Decorator用的是包含的方式。Proxy模式,或者準(zhǔn)確地說DynamicProxy模式,是現(xiàn)代AOP框架實(shí)現(xiàn)中的一種常用方式。典型的實(shí)現(xiàn)如SpringJBoss以及Castle Project中的Aspect#。

實(shí)現(xiàn):

繼承,并在過載方法中添加需要的修飾功能。

重構(gòu)成本:

低。

3 行為型

3.1 Interpreter

 


思想:

當(dāng)有一個(gè)語言需要解釋執(zhí)行, 并且你可將該語言中的句子表示為一個(gè)抽象語法樹時(shí),定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子。

場景:

其實(shí),從物理結(jié)構(gòu)上,該模式的代碼架構(gòu)看起來可能和Composite模式一模一樣,致使其針對(duì)的邏輯語義不同。Composite模式描述一種一般的整體和部分使用接口上的一致性,而Interpreter模式則側(cè)重于語言解釋器的實(shí)現(xiàn)構(gòu)架。

實(shí)現(xiàn):

如上圖,基本同Composite模式。

重構(gòu)成本:

高。

3.2 Iterator

 


思想:

提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素, 而又不需暴露該對(duì)象的內(nèi)部表示。

場景:

訪問一個(gè)聚合對(duì)象的內(nèi)容而無需暴露它的內(nèi)部表示。支持對(duì)聚合對(duì)象的多種遍歷。為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口(, 支持多態(tài)迭代)。

實(shí)現(xiàn):

其實(shí)就是定義一個(gè)邏輯上類似一個(gè)指針的迭代類。專門用于這種迭代工作。如果對(duì)C++ STL火鍋功夫?qū)W習(xí)的朋友一定不會(huì)陌生啦。實(shí)際使用過一下就明白了。除了功能之外,他給我最大的感受就是他讓我熟悉的for(int i = 0; i < list.Count; i++)語句,變長了好多。^-^

重構(gòu)成本:

中。

3.3 Mediator

 


思想:

用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。

場景:

該模式主要用來進(jìn)行降低一組相互關(guān)聯(lián)調(diào)用的對(duì)象間的耦合度。如果您發(fā)現(xiàn)您的系統(tǒng)的某部分的一組對(duì)象間調(diào)用極其頻繁的壞味道的話,可能您需要考慮使用該模式來進(jìn)行一些解耦,否則,這些對(duì)象中的任何一個(gè)的修改,都將可能導(dǎo)致其他對(duì)象許多地方的修改,可維護(hù)性就降低了。

實(shí)現(xiàn):

定義一個(gè)專門的中介對(duì)象來封裝和傳遞一組對(duì)象間的調(diào)用。

重構(gòu)成本:

中。

3.4 Memento

 


思想:

用在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。

場景:

該模式主要用來實(shí)現(xiàn)類似我們在常見的編輯器中經(jīng)常執(zhí)行的UndoCtrl+Z)操作。實(shí)際上就是在外部保持一組對(duì)象的某一時(shí)刻的狀態(tài),并在需要的另一個(gè)時(shí)候?qū)⑦@組對(duì)象回復(fù)到之前的狀態(tài)。

實(shí)現(xiàn):

該模式其實(shí)主要是一種對(duì)象狀態(tài)的暫存和回復(fù)的思想。上面的UML圖是一種比較典型的實(shí)現(xiàn)方式——定一個(gè)專門用于保存類狀態(tài)的類,為被保存狀態(tài)的類定義返回當(dāng)前狀態(tài)類實(shí)例,和根據(jù)狀態(tài)類實(shí)例回復(fù)對(duì)象狀態(tài)的接口。實(shí)際上也不必太拘泥于這個(gè)實(shí)現(xiàn),簡單情形下,我們完全可以利用任何的已有的對(duì)象持久化或者序列化機(jī)制來用一個(gè)字符串暫存對(duì)象的當(dāng)前完整狀態(tài)。

重構(gòu)成本:

低。

3.5 Template Method

 


思想:

定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

場景:

該模式實(shí)際上是一種非常直觀和可理解的OO思想下的代碼重用的實(shí)現(xiàn)。只需一次性實(shí)現(xiàn)一個(gè)算法的不變的部分,并將可變的行為留給子類來實(shí)現(xiàn)。各子類中公共的行為應(yīng)被提取出來并集中到一個(gè)公共父類中以避免代碼重復(fù)。模板方法只允許在特定點(diǎn)計(jì)算法的某個(gè)階段被過載,這樣也就只允許在這些點(diǎn)進(jìn)行擴(kuò)展。

實(shí)現(xiàn):

見上圖,太簡單了,就不多說了。

重構(gòu)成本:

低。

3.6 Chain of Responsibility

 


思想:

使多個(gè)對(duì)象都有機(jī)會(huì)處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個(gè)對(duì)象處理它為止。

場景:

該模式實(shí)際上是對(duì)人們常會(huì)不自覺地去做的一種代碼組織方式的總結(jié)而已。有的時(shí)候一條消息需要被處理,我們當(dāng)然可以在一個(gè)雷的一個(gè)方法中對(duì)他進(jìn)行所有需要的處理。但是,如果要做的處理很復(fù)雜的情形,甚至能夠按照一定的邏輯醒來分類所有這些處理,則不要在一個(gè)雷一個(gè)函數(shù)里處以一切會(huì)更好,我們可以定義多個(gè)處理類類表示邏輯上的不同的處理,然后一個(gè)個(gè)處理類的傳遞這個(gè)消息對(duì)象,讓希望處理該消息的類自己決定是不是要處理。這樣,就能將一個(gè)難以維護(hù)的復(fù)雜處理過程,分解為一系列簡單明了,易于維護(hù)的類了。

實(shí)現(xiàn):

上圖是實(shí)現(xiàn)方式之一。即,使所有可能處理該請求的對(duì)象繼承自一個(gè)基類,實(shí)際上,只要邏輯語義上我們保持這樣一種讓每個(gè)處理類自己決定何時(shí)處理,并傳遞請求的思想,實(shí)現(xiàn)方式也可以千變?nèi)f化,無論是用接口代替,或者甚至只是簡單的定義相同結(jié)構(gòu)的處理函數(shù)而通過反射機(jī)制來調(diào)用處理函數(shù)和傳遞處理請求,都是可選的方案。

重構(gòu)成本:

中。

3.7 Command

 


思想:

將一個(gè)動(dòng)態(tài)的執(zhí)行過程封裝成一個(gè)對(duì)象,可以像處理數(shù)據(jù)來處理和管理這樣的對(duì)象,在需要的時(shí)候激發(fā)該對(duì)象的方法就能執(zhí)行被封裝的執(zhí)行過程。

場景:

該模式在很多時(shí)候非常有用,它使得我們對(duì)邏輯上已經(jīng)激發(fā)的行為進(jìn)行優(yōu)化成為可能,我們不僅可以根據(jù)需要改變一組邏輯上以經(jīng)濟(jì)法的活動(dòng)的順序,消冗余操作,撤銷不必要的操作等。也可以把活動(dòng)和操作視為資源一樣來管理和重用。同時(shí)該模式也是許多事務(wù)處理機(jī)制的基礎(chǔ)。

實(shí)現(xiàn):

實(shí)現(xiàn)很簡單,只是定義一些能夠通過指定接口被激發(fā)的對(duì)活動(dòng)進(jìn)行封裝的類,然后我們按照需要管理這些類,并在需要的時(shí)候激發(fā)這些活動(dòng)。您還是應(yīng)該更多地去體會(huì),為什么他是事務(wù)處理機(jī)制的基礎(chǔ),當(dāng)我們可以這樣來管理一組活動(dòng)的時(shí)候,可以對(duì)這些活動(dòng)進(jìn)行那些有趣的控制。

重構(gòu)成本:

高。

3.8 Observer

 


思想:

定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí), 所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。

場景:

上面描述該模式思想的文字可能顯得有些拗口,實(shí)際上你也不用想得過于復(fù)雜。只要你寫過任何的基于圖形界面的程序,那么實(shí)際上您對(duì)他是一點(diǎn)也不該陌生的。它就是我們每一次鼠標(biāo)鍵盤敲擊都在我們的程序內(nèi)部流轉(zhuǎn)著的事件機(jī)制的基礎(chǔ)。當(dāng)一個(gè)事件發(fā)生,則通知訂閱該事件的對(duì)象。

實(shí)現(xiàn):

上面的UML圖看似復(fù)雜,實(shí)際上,去理解它的最好的辦法就是試著思考和使用任何一種OO語言來定義一個(gè)擁有事件機(jī)制的類。比如,.Net下,你只要好好去看看關(guān)于delegate的文檔,嘗試著根據(jù)MSDN寫寫看一個(gè)最簡單的自定義事件。那么,上面的UML圖,我敢保證你能很輕易的看明白。

重構(gòu)成本:

高。

3.9 State

 


思想:

允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。

場景:

實(shí)際上該模式在作為重構(gòu)的目的是,絕大多數(shù)情況我們做的事情是將對(duì)一個(gè)類的state進(jìn)行if-else或者select-case,決定該執(zhí)行什么操作的過程解耦的過程。

實(shí)現(xiàn):

將表述一個(gè)類的某些操作該做什么,該怎么做的信息保存到其state中。即用一個(gè)包含更多信息,甚至執(zhí)行邏輯的state類實(shí)例來代替一個(gè)簡單數(shù)據(jù)類型的state屬性。

重構(gòu)成本:

中。

3.10 Strategy

 


思想:

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

場景:

該模式實(shí)際上也可以理解為一種Bridge模式的變種。只是它突出的是,一般當(dāng)我們把一個(gè)類或者一組類的一些代碼獨(dú)立成一個(gè)Strategy類的時(shí)候,我們可能會(huì)為同樣接口的這些算法定義多個(gè)接口一致,但是實(shí)現(xiàn)方法不同的版本,并在需要的時(shí)候靈活的替換這些算法。

實(shí)現(xiàn):

實(shí)現(xiàn)方式同Bridge模式。

重構(gòu)成本:

中。

3.11 Visitor

 


思想:

表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。

場景:

其實(shí)你不用去理解上面這句話。該模式其實(shí)又是一個(gè)在代碼的物理結(jié)構(gòu)上和Bridge模式很相似的模式。但是,其語義,其目的,在邏輯上又是不同的。如果說Bridge,以及上述我稱為可視為Bridge擴(kuò)展的模式中,作為參數(shù)的Bridge類,是作為調(diào)用類的被訪問對(duì)象的話,Visitor,在大多數(shù)情形下,如其英文含義,它在語義上是完全相反的。不是他被調(diào)用的類處理,更大程度上它處于主動(dòng)狀態(tài),是它去訪問,去處理調(diào)用它的類。調(diào)用它的類,把自己對(duì)別人隱藏起來的東西,暴露給Visitor品嘗,任君蹂躪(這個(gè),這個(gè)~~千萬別想歪了;-))。另一方面,即使邏輯上沒有這種Visitor主動(dòng)去訪問調(diào)用類的語義,只要Visitor類中的操作,是依賴于調(diào)用類的具體實(shí)現(xiàn)類(它本身或他某個(gè)層次的子類)的某些狀態(tài)或者方法的,那么,就可以應(yīng)用該模式來分離出這樣的可重用的操作。

實(shí)現(xiàn):

類似Bridge模式。

重構(gòu)成本:

中。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲男女性生活免费视频| 亚洲精品福利视频在线观看| 亚洲国产精品久久琪琪| 激情综合五月开心久久| 日韩一区二区三区观看| 免费亚洲黄色在线观看| 色婷婷人妻av毛片一区二区三区| 91人妻人人澡人人人人精品| 扒开腿狂躁女人爽出白浆av| 亚洲少妇一区二区三区懂色| 国产日产欧美精品大秀| 日韩欧美精品一区二区三区 | 精品精品国产欧美在线| 日韩欧美在线看一卡一卡| 亚洲av一区二区三区精品| 中文字幕人妻av不卡| 九九蜜桃视频香蕉视频| 人妻少妇久久中文字幕久久| 免费亚洲黄色在线观看| 日本高清一道一二三区四五区| 日本加勒比在线观看不卡| 男人的天堂的视频东京热| 麻豆欧美精品国产综合久久| 一区二区三区欧美高清| 欧美日韩亚洲国产综合网| 午夜视频免费观看成人| 丰满人妻少妇精品一区二区三区| 午夜福利国产精品不卡| 国产内射一级一片内射高清| 午夜国产成人福利视频| 夫妻激情视频一区二区三区| 免费大片黄在线观看日本| 天堂网中文字幕在线视频| 麻豆一区二区三区在线免费| 国产亚洲中文日韩欧美综合网| 亚洲精品中文字幕无限乱码| 日韩中文字幕人妻精品| 欧美尤物在线视频91| 国产男女激情在线视频| 国产福利在线播放麻豆| 亚洲免费黄色高清在线观看|