访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。
其缺点就是增加新的数据结构很困难。
简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。被访问数据不用修改。
visitor里包含了访问所有visitable子类实例的方法。
被访问者抽象类Node.java
package com.javapatterns.visitor.visitorsimplified;
abstract public class Node
{
public abstract void accept(Visitor visitor);
/** @link dependency */
/*# Visitor lnkVisitorA; */
}
被访问者实现类NodeA .java
package com.javapatterns.visitor.visitorsimplified;
public class NodeA extends Node
{
public void accept(Visitor visitor)
{
visitor.visit(this);
}
public String operationA()
{
return "NodeA is visited";
}
}
被访问者实现类NodeB .java
package com.javapatterns.visitor.visitorsimplified;
public class NodeB extends Node
{
public void accept(Visitor visitor)
{
visitor.visit(this);
}
public String operationB()
{
return "NodeB is visited";
}
}
访问者类Visitor.java
package com.javapatterns.visitor.visitorsimplified;
public class Visitor
{
public void visit(NodeA nodeA)
{
System.out.println( nodeA.operationA() );
}
public void visit(NodeB nodeB)
{
System.out.println( nodeB.operationB() );
}
}
增加与迭代被访问者类ObjectStructure.java
package com.javapatterns.visitor.visitorsimplified;
import java.util.Vector;
import java.util.Enumeration;
public class ObjectStructure
{
private Vector nodes;
/**
* @link aggregation
*/
private Node node;
public ObjectStructure()
{
nodes = new Vector();
}
public void action(Visitor visitor)
{
for(Enumeration e = nodes.elements();
e.hasMoreElements();)
{
node = (Node) e.nextElement();
node.accept(visitor);
}
}
public void add(Node node)
{
nodes.addElement(node);
}
}
客户端类Client.java
package com.javapatterns.visitor.visitorsimplified;
public class Client
{
private static ObjectStructure aObjects;
private static Visitor visitor;
static public void main(String[] args)
{
aObjects = new ObjectStructure();
aObjects.add(new NodeA());
aObjects.add(new NodeB());
visitor = new Visitor();
aObjects.action(visitor);
}
}