Visitor模式,在不修改已有程序結(jié)構(gòu)的前提下,通過添加額外的“訪問者”來完成對已有代碼功能的提升。
Visitor模式包括以下幾個(gè)元素:

1) 訪問者接口(Visitor):聲明一個(gè)訪問接口,定義visit接口,有幾個(gè)元素就定義幾個(gè)接口方法。接口方法的參數(shù)標(biāo)識了具體訪問元素角色,也就是說參數(shù)是一個(gè)具體類。這個(gè)地方也是Visitor的不足,

2) 具體訪問者(Concrete Visitor):實(shí)現(xiàn)Visitor接口

3) 元素接口(Element):定義一個(gè)accept方法,它以訪問者接口為參數(shù),這里不是具體的訪問者,即不知道具體的訪問者。

4) 具體元素(Concrete Element):實(shí)現(xiàn)元素(Element)接口中accept方法,控制訪問的流程。

5) 對象結(jié)構(gòu)(Object Structure):這是使用Visitor模式必須的角色。它要具備以下特征:能枚舉它的元素;可以提供一個(gè)高層的接口允許訪問者訪問它的元素;可以是一個(gè)集合,如一個(gè)列表或一個(gè)無序集合。

類圖如下:


具體代碼:

public interface Visitor
{
 
public void visitCollection(Collection collection);
 
public void visitString(String string);
 
public void visitFloat(Float float);
}

public class ConcreteVisitor1 implements Visitor
{
 
//在本方法中,我們實(shí)現(xiàn)了對Collection的元素的成功訪問
   public void visitCollection(Collection collection) {
    Iterator iterator 
= collection.iterator()
    
while (iterator.hasNext()) {
       Object o 
= iterator.next();
       
if (o instanceof Visitable)
          ((Visitable)o).accept(
this);
    }

 
public void visitString(String string) {
    System.out.println(
"'"+string+"'");
 }

 
public void visitFloat(Float float) {
    System.out.println(
float.toString()+"f");
 }
}

public interface Visitable
{
 
public void accept(Visitor visitor);


public class StringElement implements Visitable
{
 
private String value;
 
public ConcreteElement(String string) {
    value 
= string;
 }
 
//定義accept的具體內(nèi)容 這里是很簡單的一句調(diào)用
   public void accept(Visitor visitor) {
    visitor.visitString(
this);
 }
}


public class FloatElement implements Visitable
{
 
private Float value;
 
public ConcreteElement(Float f) {
    value 
= f;
 }
 
//定義accept的具體內(nèi)容 這里是很簡單的一句調(diào)用
   public void accept(Visitor visitor) {
    visitor.visitFloat(
this);
 }
}

總結(jié):
1、元素接口和元素類都是依賴Visitor接口,而不是具體實(shí)現(xiàn)類,很好的實(shí)現(xiàn)了解耦。如果有一個(gè)新的元素歡迎Visitor參觀,只需要實(shí)現(xiàn)Visitable接口,并實(shí)現(xiàn)accept方法即可,都不牽涉具體的Visitor。

2、Visitor接口則不然,它依賴具體的元素,也就是說如果元素的類型發(fā)生變化如增加一個(gè)元素類型,那么Visitor接口和具體實(shí)現(xiàn)類都必須大改,這個(gè)是Visitor模式嚴(yán)重的缺陷。

3、Visitor模式名副其實(shí),好比旅行社、游客和景點(diǎn)的關(guān)系。旅行社就是Visitor接口,這次路線都需要參觀哪些景點(diǎn)通常是固定的(接口固定,如果要改變行程,通常很麻煩);游客就這些景點(diǎn),旅行社給你安排兩個(gè)小時(shí),你想自己怎么玩都行;景點(diǎn)則以不變應(yīng)萬變。這個(gè)比如也許有些不恰當(dāng),不過有助于理解這個(gè)模式。