一、定义
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
双分派:对于消息表达式a.m(b),能够按照a和b的实际类型为其绑定对应方法体。
二、示例代码
public abstract class Element {
public abstract void accept(Visitor visitor);
}
public class ConcreteElementA extends Element{
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementA(this);
}
}
public class ConcreteElementB extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementB(this);
}
}
public abstract class Visitor {
public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}
public class ConcreteVisitor1 extends Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("对象:" + concreteElementA.getClass().getName() + "被" + concreteElementA.getClass().getName() + this.getClass().getName() + "访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("对象:" + concreteElementB.getClass().getName() + "被" + concreteElementB.getClass().getName() + this.getClass().getName() + "访问");
}
}
public class ConcreteVisitor2 extends Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("对象:" + concreteElementA.getClass().getName() + "被" + concreteElementA.getClass().getName() + this.getClass().getName() + "访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("对象:" + concreteElementB.getClass().getName() + "被" + concreteElementB.getClass().getName() + this.getClass().getName() + "访问");
}
}
public class ObjectStructure {
private List<Element> elements = new ArrayList<Element>();
public void attach(Element element) {
elements.add(element);
}
public void detach(Element element) {
elements.remove(element);
}
public void accept(Visitor visitor) {
for (Element e : elements
) {
e.accept(visitor);
}
}
}
public class Client {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new ConcreteElementA());
objectStructure.attach(new ConcreteElementB());
Visitor concreteVisitor1 = new ConcreteVisitor1();
Visitor concreteVisitor2 = new ConcreteVisitor2();
objectStructure.accept(concreteVisitor1);
objectStructure.accept(concreteVisitor2);
}
}