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接口,这次路线都需要参观哪些景点通常是固定的(接口固定,如果要改变行程,通常很麻烦);游客就这些景点,旅行社给你安排两个小时,你想自己怎么玩都行;景点则以不变应万变。这个比如也许有些不恰当,不过有助于理解这个模式。