访问者模式是在编译器的解析器常用的设计模式,例如,Eclipse JDT AST解析器。
基本上,在访问者模式中有两个接口——访问者和元素。
1、访问者的故事
假设有一个第一次来到纽约的游客。他想去游览这个城市而且这个城市也接收他游览。一旦游客开始游览,就会自动游览所有的事物,并且当他想去一个博物馆的时候他不必去调用任何方法。这个旅游是一个package!
2、访问者模式类图
3、访问者模式的步骤
下面的图显示游览的步骤
工作流程就像下面描述的:
1.一个访问者FirstTimeVisitor和一个元素City被创建。
2.程序开始于"City accept a visitor"。
3.在City类中的accept方法定义了让这个访问者去访问。
4.被接受的访问者调用它的重载的方法"visit"来游览这个City。
4、访问者模式Java代码
public interface Element {
public void accept(Visitor visitor);
}
public interface Visitor {
public void visit(City city);
public void visit(Museum museum);
public void visit(Park park);
}
public class City implements Element {
private List<Element> places = new ArrayList<Element>();
public City() {
places.add(new Museum());
places.add(new Park());
}
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
System.out.println("这个城市接收了这个访问者!");
visitor.visit(this);
for (Element e : places) {
e.accept(visitor);
}
}
}
public class Museum implements Element {
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
System.out.println("Museum接收了这个访问者!");
visitor.visit(this);
}
}
public class Park implements Element {
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
System.out.println("Park接收了这个访问者!");
visitor.visit(this);
}
}
public class FirstTimeVisitor implements Visitor {
@Override
public void visit(City city) {
// TODO Auto-generated method stub
System.out.println("我正在游览这个城市!");
}
@Override
public void visit(Museum museum) {
// TODO Auto-generated method stub
System.out.println("我正在游览这个博物馆!");
}
@Override
public void visit(Park park) {
// TODO Auto-generated method stub
System.out.println("我正在游览这个公园!");
}
}
public class Test {
public static void main(String[] args) {
FirstTimeVisitor visitor = new FirstTimeVisitor();
City city = new City();
city.accept(visitor);
}
}
输出:
这个城市接收了这个访问者!
我正在游览这个城市!
Museum接收了这个访问者!
我正在游览这个博物馆!
Park接收了这个访问者!
我正在游览这个公园!
我正在游览这个城市!
Museum接收了这个访问者!
我正在游览这个博物馆!
Park接收了这个访问者!
我正在游览这个公园!
5、JDK中实际应用
javax.lang.model.element.AnnotationValue显然用了访问者模式,但它在正常的工程中不常用到。