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

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

2) 具體訪問者(Concrete Visitor):實現Visitor接口

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

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

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

類圖如下:


具體代碼:

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

public class ConcreteVisitor1 implements Visitor
{
 
//在本方法中,我們實現了對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的具體內容 這里是很簡單的一句調用
   public void accept(Visitor visitor) {
    visitor.visitString(
this);
 }
}


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

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

2、Visitor接口則不然,它依賴具體的元素,也就是說如果元素的類型發生變化如增加一個元素類型,那么Visitor接口和具體實現類都必須大改,這個是Visitor模式嚴重的缺陷。

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