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




·被訪問(wèn)者接口實(shí)現(xiàn)類(lèi)
















·訪問(wèn)者接口








·訪問(wèn)者接口實(shí)現(xiàn)類(lèi)



















·客戶端調(diào)用代碼












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