訪問者模式(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而不需要使用訪問者的,但是訪問者能夠給客戶端提供更加統一一致的操作方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章