談到設計模式,絕對應該一起來說說重構(gòu)。重構(gòu)給我們帶來了什么?除了作為對遺留代碼的改進的方法,另一大意義在于,可以讓我們在寫程序的時候可以不需事先考慮太多的代碼組織問題,當然這其中也包括了應用模式的問題。盡管大多數(shù)開發(fā)者都已經(jīng)養(yǎng)成了寫代碼前先從設計開始的習慣,但是,這種程度的設計,涉及到到大局、到總體架構(gòu)、到主要的模塊劃分我覺得就夠了。換句話說,這時就能寫代碼了。這就得益于重構(gòu)的思想了。如果沒有重構(gòu)的思想,有希望獲得非常高質(zhì)量的代碼,我們就不得不在開始寫代碼前考慮更多其實并非非常穩(wěn)定的代碼組織及設計模式的應用問題,那開發(fā)效率當然就大打折扣了。在重構(gòu)和設計模式的合理應用之下,我們可以相對較早的開始寫代碼,并在功能盡早實現(xiàn)的同時,不斷地通過重構(gòu)和模式來改善我們的代碼質(zhì)量。所以,下面的章節(jié)中,在談模式的同時,我也會談談關于常用的這些模式的重構(gòu)成本的理解。重構(gòu)成本越高意味著,在遇到類似的問題情形的時候,我們更應該提前考慮應用對應的設計模式,而重構(gòu)成本比較低則說明,類似的情形下,完全可以先怎么方便,怎么快怎么寫,哪怕代碼不是很優(yōu)雅也沒關系,回頭再重構(gòu)也很容易。
思想:
Factory Method的主要思想是使一個類的實例化延遲到其子類。
場景:
典型的應用場景如:在某個系統(tǒng)開發(fā)的較早階段,有某些類的實例化過程,實例化方式可能還不是很確定,或者實際實例化的對象(可能是需要對象的某個子類中的一個)不確定,或者比較容易變化。此時,如果直接將實例化過程寫在某個函數(shù)中,那么一般就是if-else或select-case代碼。如果,候選項的數(shù)目較少、類型基本確定,那么這樣的if-else還是可以接受的,一旦情形變得復雜、不確定性增加,更甚至包含這個構(gòu)造過程的函數(shù)所在的類包含幾個甚至更多類似的函數(shù)時,這樣的if-else代碼就會變得比較不那么容易維護了。此時,應用本模式,可以將這種復雜情形隔離開,即將這類不確定的對象的實例化過程延遲到子類。
實現(xiàn):
該模式的典型實現(xiàn)方法就是將調(diào)用類定義為一個虛類,在調(diào)用類定義一個專門用于構(gòu)造不確定的對象實例的虛函數(shù),再將實際的對象實例化代碼留到調(diào)用類的子類來實現(xiàn)。如果,被構(gòu)造的對象比較復雜的話,同時可以將這個對象定義為可以繼承、甚至虛類,再在不同的調(diào)用類的子類中按需返回被構(gòu)造類的子類。
重構(gòu)成本:
低。該模式的重構(gòu)成本實際上還與調(diào)用類自己的實例化方式相關。如果調(diào)用類是通過Factory方式(此處“Factory方式”泛指對象的實例化通過Factory Method或Abstract Factory這樣的相對獨立出來的方式構(gòu)造)構(gòu)造的,那么,重構(gòu)成本相對就會更低。否則,重構(gòu)時可能除了增加調(diào)用類的子類,還要將所有實例化調(diào)用類的地方,修改為以新增的子類代替??赡苓@樣的子類還不止一個,那就可以考慮迭代應用模式來改善調(diào)用類的實例化代碼。
思想:
不直接通過對象的具體實現(xiàn)類,而是通過使用專門的類來負責一組相關聯(lián)的對象的創(chuàng)建。
場景:
最典型的應用場景是:您只想暴露對象的接口而不想暴露具體的實現(xiàn)類,但是又想提供實例化對象的接口給用戶;或者,您希望所有的對象能夠集中在一個或一組類(通常稱作工廠類)來創(chuàng)建,從而可以更方便的對對象的實例化過程進行動態(tài)配置(此時只需要修改工廠類的代碼或配置)。
實現(xiàn):
該模式的實現(xiàn)是比較清晰簡單的,如上圖,就是定義創(chuàng)建和返回各種類對象實例的工廠類。在最復雜而靈活的情形,無論工廠類本身還是被創(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ù)量相關。您需要根據(jù)實際情況考慮,是否工廠類要映射被創(chuàng)建對象的所有重載版本的構(gòu)造函數(shù)。
思想:
將一個類的創(chuàng)建過程和他的主體部分分離。
場景:
該模式的典型的應用場景是:一個類的創(chuàng)建過程可能比較復雜,或者創(chuàng)建過程中的某些階段可能會容易變化;或者多個類的創(chuàng)建過程比較類似,但是主體不同。
實現(xiàn):
在以上提到的兩種場景中,我們就可以取出一個類的創(chuàng)建過程的代碼,定義一個專門的Builder類,而在原來創(chuàng)建類對象實例的地方,將這個Builder類的實例作為參數(shù)傳入。還有第二個重點,就是Builder類可以將將整個創(chuàng)建過程分為幾個階段,每個階段不必在類中直接實現(xiàn),而可以通過繼承體系在子類中實現(xiàn),或者通過子類的方法過載來修改創(chuàng)建過程中的某個階段,但是重用其他的階段。可以發(fā)現(xiàn),該模式將一個對象的復雜創(chuàng)建過程重用到非常高的層次。這正是它的意義所在。
重構(gòu)成本:
低。該模式的重構(gòu)成本我覺得是非常低的,因為一般來講,創(chuàng)建過程的代碼本來也就應該在原來的類的構(gòu)造函數(shù)中,把它Extract出來就好了。如果發(fā)現(xiàn)多個類的創(chuàng)建過程有比較多的代碼重復或類似,那么就可以重用這些提取出來的Builder類或者Builder類中的某些階段。
思想:
克隆一個已有的類的實例(大家相比都用過甚至寫過類的Clone實現(xiàn),應該很容易理解了)。
場景:
應用Clone的場景應該說非常多,理想情況下我當然希望任何類都能Clone,需要的時候就能Clone一份一模一樣的出來。
實現(xiàn):
這里將的實現(xiàn)主要之實現(xiàn)的表現(xiàn)形式,而不是如何用具體的語言來實現(xiàn)。因此,只要為需要Clone能力的類定義一個Clone方法就行。當然,一般,主流的程序語言框架都已經(jīng)定義了通用的Clone接口(當然也可以自己定義),繼承并實現(xiàn)該接口和方法就好。
重構(gòu)成本:
極低。不多解釋了吧。
思想:
保證一個類只有一個唯一的實例。
場景:
生活中有些對象就是只要一個就好了,我們的代碼中為什么要每次都為這樣的對象生成一個實例呢?
實現(xiàn):
最簡單的實現(xiàn)方式就是使用一個static型的類實例,每次對該對象的創(chuàng)建請求都返回這個static的唯一實例就行。
重構(gòu)成本:
極低。
思想:
將一個類的接口轉(zhuǎn)換成另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
場景:
該模式的應用場景太多了,很多需要的功能模塊的接口和我們需要的不完全一致或者有多余或不足,但是需要和我們的系統(tǒng)協(xié)同工作,通過Adapter把它包裝一下就能讓使它接口兼容了。
實現(xiàn):
定義一個Adapter類,包含需要包裝的類,實現(xiàn)需要的其它接口,調(diào)用被包裝的類的方法來實現(xiàn)需要的接口。
重構(gòu)成本:
低。
思想:
將一個類的抽象定義和具體實現(xiàn)解耦。
場景:
該模式的典型應用場景是:一個類的抽象定義已經(jīng)確定,但是,其實現(xiàn)代碼甚至原理可能會不同。比如:我們最熟悉的圖形界面中的window的實現(xiàn),無論在什么操作系統(tǒng),什么平臺的機器上,一個window應具有的抽象定義基本上是一致的,但是,其實現(xiàn)代碼肯定會因為平臺不同,機器的代碼指令不同而不同。此時,如果希望您寫的window類能跨平臺,應用Bridge模式就是一個好主意。
實現(xiàn):
該模式的實現(xiàn)方法很簡單,就是除了定義類的抽象定義之外,將一個類的所有實現(xiàn)代碼獨立出一個實現(xiàn)類。這樣一來,無論是抽象定義還是實現(xiàn)類都能分別修改和重用,但只要兩部分的交互接口不變,還是可以方便的互相組裝。當然,實際上也沒有必要隔離出“所有實現(xiàn)代碼”,只需要隔離需要的部分就行了。因此,也可以說,從代碼結(jié)構(gòu)來看,Builder模式是一種變種的Bridge模式的。也經(jīng)常有人將Bridge模式和接口相比較,如果隔離出所有的實現(xiàn),那么的確接口的方式也能做到抽象定義和實現(xiàn)分離,但是,Bridge有其優(yōu)勢如下:一、究竟隔離多少代碼到Bridge類中可以靈活確定,二、減少了總的類的數(shù)目,三、允許被隔離出來的Bridge類被其它的類直接共享使用。
重構(gòu)成本:
中。將所有的(或很大部分)實現(xiàn)代碼分離開來總還是一件不大,但是,也不小的事。所以標個“中”在這里。:)
思想:
將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對單個對象和組合對象的使用具有一致性。
場景:
該模式的應用場景極其類似,比如像圖形系統(tǒng),如電路設計、UML建模系統(tǒng),或者像web的顯示元素等,都是那種需要整體和部分具有使用接口上的一定的一致性的需求的結(jié)構(gòu),實際上,我覺得這樣的系統(tǒng)如果不使用Composite模式將會是慘不忍睹的。
實現(xiàn):
該模式的實現(xiàn)主要就是要表示整體或部分的所有類都繼承自同一的基類或接口,從而擁有使用接口上一定的一致性。
重構(gòu)成本:
高。
思想:
為一個對象已有的子類添加一些額外的職責。
場景:
該模式的使用場景,主要是有的時候我們不愿意定義邏輯上新的子類,因為沒有新的邏輯含義上的子類概念,而只是想為一個已存在的子類附加一些職責。
實現(xiàn):
該模式的實現(xiàn)主要就是定義一個物理上的新的子類,但是,它只是包含要附加職責的類,傳遞外部對相同接口的調(diào)用,在這個傳遞調(diào)用的通道上附加額外的功能。突然想到,Decorator模式是不是一定程度上也能代替DynamicProxy模式,從而成為一種AOP實現(xiàn)的方案呢?
重構(gòu)成本:
低。定義一個Decorator和一個已有類的邏輯上的子類,物理表現(xiàn)形式上都是一個子類,重構(gòu)也確實不是難事。
思想:
為子系統(tǒng)中的一組接口提供一個一致的界面,這個接口使得這一子系統(tǒng)更加容易使用。
場景:
當你要為一個復雜子系統(tǒng)提供一個簡單接口時。子系統(tǒng)往往因為不斷演化而變得越來越復雜。大多數(shù)模式使用時都會產(chǎn)生更多更小的類。這使得子系統(tǒng)更具可重用性,也更容易對子系統(tǒng)進行定制,但這也給那些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難。Facade可以提供一個簡單的缺省視圖,這一視圖對大多數(shù)用戶來說已經(jīng)足夠,而那些需要更多的可定制性的用戶可以越過Facade層??蛻舫绦蚺c抽象類的實現(xiàn)部分之間存在著很大的依賴性。引入Facade將這個子系統(tǒng)與客戶以及其他的子系統(tǒng)分離,可以提高子系統(tǒng)的獨立性和可移植性。當你需要構(gòu)建一個層次結(jié)構(gòu)的子系統(tǒng)時,使用Facade模式定義子系統(tǒng)中每層的入口點。如果子系統(tǒng)之間是相互依賴的,你可以讓它們僅通過Facade進行通訊,從而簡化了它們之間的依賴關系。(這里直接引用了《設計模式迷你手冊》,因為覺得它確實已經(jīng)說得很明了了,下面類似的情形我直接引用原文的就不再注明了,這里先說明一下,感謝《手冊》作者的這些優(yōu)秀總結(jié)。當然,本文的絕大多數(shù)文字都是Teddy本人的原創(chuàng)看法,絕非抄襲,您可以比較本文和附件《手冊》,附件同時也會提供本文的Word版本下載。)
實現(xiàn):
該模式的實現(xiàn)需要定義一個新的系統(tǒng)構(gòu)架上的Layer,該層向上提供一組新的接口,向下調(diào)用子系統(tǒng)原有的接口。
重構(gòu)成本:
高。要修改所有直接對子系統(tǒng)的地調(diào)用為對Façade層的調(diào)用還是有很多事情要做的。不過,現(xiàn)代IDE中,如果我們刪除調(diào)用層對子系統(tǒng)的程序集引用,那么所有這些我們需要修改的調(diào)用都能標示出來,因為編譯不能通過了嘛,因此,重構(gòu)的風險還不算特別大,只是工作量著實不小。
思想:
說Flyweight可能有的朋友第一次看到想象不到是什么樣子,其實說他就是一個Pool,你可能就明白了。也就是由一個Flyweight Factory來管理一族一定數(shù)目邏輯上經(jīng)常需要構(gòu)建和銷毀的細顆粒對象,例如我們常見的數(shù)據(jù)庫連接池。在Factory內(nèi)部,并不物理銷毀這些對象,而在接到實例化請求時返回這些被關系對象的實例,從而減少創(chuàng)建銷毀這些細顆粒對象的開銷。
場景:
基本上所有的需要Pool這個概念的環(huán)境都能應用。
實現(xiàn):
實現(xiàn)的底層方式可以千變?nèi)f化,在接口上就是如上圖所示,花樣不多。這里就不多解釋。
重構(gòu)成本:
低。
思想:
前面在Decorator模式中也提到了Proxy模式了。它是通過邏輯上繼承一個已有類的子類,從而擴展原有的子類的功能。
場景:
需要注意體會他和Decorator的需別。Proxy是繼承需要修飾的類,而Decorator用的是包含的方式。Proxy模式,或者準確地說DynamicProxy模式,是現(xiàn)代AOP框架實現(xiàn)中的一種常用方式。典型的實現(xiàn)如Spring,JBoss以及Castle Project中的Aspect#。
實現(xiàn):
繼承,并在過載方法中添加需要的修飾功能。
重構(gòu)成本:
低。
思想:
當有一個語言需要解釋執(zhí)行, 并且你可將該語言中的句子表示為一個抽象語法樹時,定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
場景:
其實,從物理結(jié)構(gòu)上,該模式的代碼架構(gòu)看起來可能和Composite模式一模一樣,致使其針對的邏輯語義不同。Composite模式描述一種一般的整體和部分使用接口上的一致性,而Interpreter模式則側(cè)重于語言解釋器的實現(xiàn)構(gòu)架。
實現(xiàn):
如上圖,基本同Composite模式。
重構(gòu)成本:
高。
思想:
提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內(nèi)部表示。
場景:
訪問一個聚合對象的內(nèi)容而無需暴露它的內(nèi)部表示。支持對聚合對象的多種遍歷。為遍歷不同的聚合結(jié)構(gòu)提供一個統(tǒng)一的接口(即, 支持多態(tài)迭代)。
實現(xiàn):
其實就是定義一個邏輯上類似一個指針的迭代類。專門用于這種迭代工作。如果對C++ STL火鍋功夫?qū)W習的朋友一定不會陌生啦。實際使用過一下就明白了。除了功能之外,他給我最大的感受就是他讓我熟悉的for(int i = 0; i < list.Count; i++)語句,變長了好多。^-^
重構(gòu)成本:
中。
思想:
用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
場景:
該模式主要用來進行降低一組相互關聯(lián)調(diào)用的對象間的耦合度。如果您發(fā)現(xiàn)您的系統(tǒng)的某部分的一組對象間調(diào)用極其頻繁的壞味道的話,可能您需要考慮使用該模式來進行一些解耦,否則,這些對象中的任何一個的修改,都將可能導致其他對象許多地方的修改,可維護性就降低了。
實現(xiàn):
定義一個專門的中介對象來封裝和傳遞一組對象間的調(diào)用。
重構(gòu)成本:
中。
思想:
用在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復到原先保存的狀態(tài)。
場景:
該模式主要用來實現(xiàn)類似我們在常見的編輯器中經(jīng)常執(zhí)行的Undo(Ctrl+Z)操作。實際上就是在外部保持一組對象的某一時刻的狀態(tài),并在需要的另一個時候?qū)⑦@組對象回復到之前的狀態(tài)。
實現(xiàn):
該模式其實主要是一種對象狀態(tài)的暫存和回復的思想。上面的UML圖是一種比較典型的實現(xiàn)方式——定一個專門用于保存類狀態(tài)的類,為被保存狀態(tài)的類定義返回當前狀態(tài)類實例,和根據(jù)狀態(tài)類實例回復對象狀態(tài)的接口。實際上也不必太拘泥于這個實現(xiàn),簡單情形下,我們完全可以利用任何的已有的對象持久化或者序列化機制來用一個字符串暫存對象的當前完整狀態(tài)。
重構(gòu)成本:
低。
思想:
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
場景:
該模式實際上是一種非常直觀和可理解的OO思想下的代碼重用的實現(xiàn)。只需一次性實現(xiàn)一個算法的不變的部分,并將可變的行為留給子類來實現(xiàn)。各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。模板方法只允許在特定點計算法的某個階段被過載,這樣也就只允許在這些點進行擴展。
實現(xiàn):
見上圖,太簡單了,就不多說了。
重構(gòu)成本:
低。
思想:
使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
場景:
該模式實際上是對人們常會不自覺地去做的一種代碼組織方式的總結(jié)而已。有的時候一條消息需要被處理,我們當然可以在一個雷的一個方法中對他進行所有需要的處理。但是,如果要做的處理很復雜的情形,甚至能夠按照一定的邏輯醒來分類所有這些處理,則不要在一個雷一個函數(shù)里處以一切會更好,我們可以定義多個處理類類表示邏輯上的不同的處理,然后一個個處理類的傳遞這個消息對象,讓希望處理該消息的類自己決定是不是要處理。這樣,就能將一個難以維護的復雜處理過程,分解為一系列簡單明了,易于維護的類了。
實現(xiàn):
上圖是實現(xiàn)方式之一。即,使所有可能處理該請求的對象繼承自一個基類,實際上,只要邏輯語義上我們保持這樣一種讓每個處理類自己決定何時處理,并傳遞請求的思想,實現(xiàn)方式也可以千變?nèi)f化,無論是用接口代替,或者甚至只是簡單的定義相同結(jié)構(gòu)的處理函數(shù)而通過反射機制來調(diào)用處理函數(shù)和傳遞處理請求,都是可選的方案。
重構(gòu)成本:
中。
思想:
將一個動態(tài)的執(zhí)行過程封裝成一個對象,可以像處理數(shù)據(jù)來處理和管理這樣的對象,在需要的時候激發(fā)該對象的方法就能執(zhí)行被封裝的執(zhí)行過程。
場景:
該模式在很多時候非常有用,它使得我們對邏輯上已經(jīng)激發(fā)的行為進行優(yōu)化成為可能,我們不僅可以根據(jù)需要改變一組邏輯上以經(jīng)濟法的活動的順序,消冗余操作,撤銷不必要的操作等。也可以把活動和操作視為資源一樣來管理和重用。同時該模式也是許多事務處理機制的基礎。
實現(xiàn):
實現(xiàn)很簡單,只是定義一些能夠通過指定接口被激發(fā)的對活動進行封裝的類,然后我們按照需要管理這些類,并在需要的時候激發(fā)這些活動。您還是應該更多地去體會,為什么他是事務處理機制的基礎,當我們可以這樣來管理一組活動的時候,可以對這些活動進行那些有趣的控制。
重構(gòu)成本:
高。
思想:
定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時, 所有依賴于它的對象都得到通知并被自動更新。
場景:
上面描述該模式思想的文字可能顯得有些拗口,實際上你也不用想得過于復雜。只要你寫過任何的基于圖形界面的程序,那么實際上您對他是一點也不該陌生的。它就是我們每一次鼠標鍵盤敲擊都在我們的程序內(nèi)部流轉(zhuǎn)著的事件機制的基礎。當一個事件發(fā)生,則通知訂閱該事件的對象。
實現(xiàn):
上面的UML圖看似復雜,實際上,去理解它的最好的辦法就是試著思考和使用任何一種OO語言來定義一個擁有事件機制的類。比如,.Net下,你只要好好去看看關于delegate的文檔,嘗試著根據(jù)MSDN寫寫看一個最簡單的自定義事件。那么,上面的UML圖,我敢保證你能很輕易的看明白。
重構(gòu)成本:
高。
思想:
允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為。
場景:
實際上該模式在作為重構(gòu)的目的是,絕大多數(shù)情況我們做的事情是將對一個類的state進行if-else或者select-case,決定該執(zhí)行什么操作的過程解耦的過程。
實現(xiàn):
將表述一個類的某些操作該做什么,該怎么做的信息保存到其state中。即用一個包含更多信息,甚至執(zhí)行邏輯的state類實例來代替一個簡單數(shù)據(jù)類型的state屬性。
重構(gòu)成本:
中。
思想:
定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。
場景:
該模式實際上也可以理解為一種Bridge模式的變種。只是它突出的是,一般當我們把一個類或者一組類的一些代碼獨立成一個Strategy類的時候,我們可能會為同樣接口的這些算法定義多個接口一致,但是實現(xiàn)方法不同的版本,并在需要的時候靈活的替換這些算法。
實現(xiàn):
實現(xiàn)方式同Bridge模式。
重構(gòu)成本:
中。
思想:
表示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
場景:
其實你不用去理解上面這句話。該模式其實又是一個在代碼的物理結(jié)構(gòu)上和Bridge模式很相似的模式。但是,其語義,其目的,在邏輯上又是不同的。如果說Bridge,以及上述我稱為可視為Bridge擴展的模式中,作為參數(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)或者方法的,那么,就可以應用該模式來分離出這樣的可重用的操作。
實現(xiàn):
類似Bridge模式。
重構(gòu)成本:
中。