作用于某個對象群中各個對象的操作. 它可以使你在不改變這些對象本身的情況下,定義作用于這些對象的新操作.在Java中,Visitor模式實際上是分離了collection結構中的元素和對這些元素進行操作的行為.
二、Visitor模式構成:
Visitor模式由被訪問者(Visitable)和訪問者(Visitor)構成,兩者之間是互動的關系,即雙方必須提供接口供彼此訪問。下面是Visitor模式的一個例子(參考自www.jdon.com)
·被訪問者接口




·被訪問者接口實現類
















·訪問者接口








·訪問者接口實現類



















·客戶端調用代碼












作為Visitor模式中的被訪問者,通常都需要定義一個setXxx和getXxx方法,為訪問者訪問時提供接口。或者像上例一樣,采用Call-back機制。而訪問者也需要提供相應的接口來接收被訪問者,以輸出其內容。
三、Visitor模式的優缺點
從這個例子就可以看出Visitor模式的一個缺點:對于集合中的所有類型元素,訪問者必須窮舉所有的可能方法,一旦元素的類型比較多,則訪問者的類將顯得比較龐大。
StringElement只是一個實現,可以拓展為更多的實現,整個核心奧妙在accept方法中,在遍歷Collection時,通過相應的accept方法調用具體類型的被訪問者。這一步確定了被訪問者類型。
Visitor模式的一個優點體現在對集合元素的訪問中:由于集合中的可訪問元素都實現了Visitable接口,所以在迭代集合的過程中,我們可以將每個元素都看成是接口類型。
其次由于JAVA語言的多態性,雖然每個元素都是接口類型(Visitable),但每個元素的實現類不同,所以在調用accept方法時,虛擬機“知道”應該調起那個正確的方法(例如:集合中的一個String元素,會調用StringElement的accept方法)
Visitor對集合類型的訪問過程:對集合進行迭代,將自身作為參數調用每個被訪問者的accept方法,被訪問者的accept方法也以自身為參數回調訪問者的visitXxx方法。
四、Visitor模式的使用前提和注意點
使用訪問者模式前提是對象群結構中(Collection) 中的對象類型很少改變。
在兩個接口Visitor和Visitable中,確保Visitable很少變化,也就是說,確保不能老有新的Element元素類型加進來,可以變化的是訪問者行為或操作,也就是Visitor的不同子類可以有多種,這樣使用訪問者模式最方便.
如果對象集合中的對象集合經常有變化, 那么不但Visitor實現要變化,Visistable也要增加相應行為,GOF建議是,不如在這些對象類中直接逐個定義操作,無需使用訪問者設計模式。
--摘自www.jdon.com的《Visitor模式》 一節
原因:
如果Visitable中元素的類型是固定的或者很少變化的,那么即使Visitor中相應的訪問行為發生改變了,對Visitable也沒有影響。相反如果Visitable中元素的類型變化頻繁,除了Visitable要增加新的類型,Visitor也要增加相應的visitXxx方法。所以說使用Visitor模式的一個前提是被訪問者的類型很少改變
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。