1. 程式人生 > >訪問者模式(Visitor Pattern)

訪問者模式(Visitor Pattern)

定義

什麼是訪問者呢?就拿身邊的一個例子來看看吧。你有一棟房子,房子裡面有很多管道、電路之類的東西,很顯然,這些東西你不懂,是別人幫你弄好的。有一天,你家的管道出問題了,於是你需要解決這個問題,但是你不懂,所以你需要找專業人員(管道修理工)來維護,這個你找的人對於你的房子來說他就是訪問者了。訪問者設計模式主要包含兩個角色:訪問者和被訪問的物件。訪問者模式將有關的行為集中到一個訪問者物件中,而不是分散到一個個的節點類中,使得增加新的操作變得很容易。如果你熟悉MVC模型,那麼可以發現,在MVC中,M是被訪問者,C是訪問者。訪問者模式是物件的行為模式。訪問者模式的目的是封裝一些施加於某種資料結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的資料結構則可以保持不變。

被訪問的物件可以是任何物件,但是,通常而言,該物件是部分-整體結構(比如組合設計模式中的組合物件)的一個節點。對於訪問者而言,他知道複雜結構中的每個節點的細節,知道如何去訪問和操作每個節點的屬性以及方法。其類圖靜態關係如下所示:

在上述所示的關係圖中,Visitor協議定義了兩個看起來很相似的visit*方法,用於訪問和處理不同的Element型別的物件。具體的訪問者ConcreteVisitor(1或2)實現了Visitor協議及其定義的方法,這些方法為特定型別的Element型別的物件定義了一些適當的操作。而客戶端手動建立訪問者物件ConcreteVisitor,然後把該物件傳給目標Element物件結構(該Element
實現了accepts通用訪問者型別的方法),此處的客戶端是知道該Element物件結構需要使用哪個訪問者的。一般而言,Element類中所實現的accept方法很相似,互相通用。通過訪問者,客戶端可以不需要直接和被訪問者接觸,他只需要請訪問者去和被訪問者接觸即可完成自己所需要的事情。

程式碼示例

(待續)

總結

當某個物件存在一些和物件依賴性低或者重複率較高的程式碼時,可以使用訪問者模式把這些程式碼移到訪問者中去,此外,當需要支援不同變化或者某些操作變化比較頻繁的時候,可以把不同版本的程式碼移植到不同的訪問者物件中去。

使用訪問者的設計模式有以下優點:

  • 擴充套件性好。可以把和資料相關的操作分佈到訪問者中去,不同的訪問者可以定義擴充套件不同的操作方法
  • 符合單一性原則。
缺點也是有的:
  • 當需要增加一種型別的Element的時候,抽象訪問者需要增加對應的抽象方法,所有已經實現的訪問者也都需要實現該方法,挺麻煩的。不過你要是讓你的訪問者不支援對該物件的訪問,那就不存在該問題了。
由於訪問者模式可以擴充套件被訪問者物件的操作型別(或者說方法),這個和IOS中的 Categories的功能很是相似,這是不是說可以使用Categories替代需要使用的訪問者呢?的卻可以僅僅使用Categories而不需要使用訪問者的,但是訪問者能夠給客戶端提供更加統一一致的操作方法。