在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
核心组成
- 访问者接口(Visitor)
定义对每一个元素类可以执行的操作,通常按元素类型重载方式。
1 2 3 4
| public interface Vistor { void visitConcreteElementA(ConcreteElementA elementA); void visitConcreteElementB(ConcreteElementB elementB); }
|
- 具体访问者类(Concrete Visitor)
实现每个操作的具体逻辑。
1 2 3 4 5 6 7 8 9 10 11
| public class ConcreteVisitor implements Visitor { @Override public void visitConcreteElementA(ConcreteElementA elementA) { System.out.println("访问者处理元素 A:" + elementA.operation()); }
@Override public void visitConcreteElementB(ConcreteElementB elementB) { System.out.println("访问者处理元素 B:" + elementB.operation()); } }
|
- 元素接口(Element)
声明一个接收访问者的方法accept
。
1 2 3
| public interface Element { void accept(Visitor visitor); }
|
- 具体元素类(Concrete Element)
实现accept
方法,调用访问者的对应方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ConcreteElementA implements Element { public String operation() { return "元素 A 的内容"; }
@Override public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); } }
public class ConcreteElementB implements Element { public String operation() { return "元素 B 的内容"; }
@Override public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); } }
|
- 对象结构(Object Structure)
管理一组元素,并提供一个让访问者访问所有元素的接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.util.ArrayList; import java.util.List;
public class ObjectStructure { private List<Element> elements = new ArrayList<>();
public void add(Element element) { elements.add(element); }
public void accept(Visitor visitor) { for (Element element : elements) { element.accept(visitor); } } }
|
- 客户端示例
1 2 3 4 5 6
| val structure = ObjectStructure() structure.add(ConcreteElementA()) structure.add(ConcreteElementB())
val visitor = ConcreteVisitor() structure.accept(visitor)
|
适用场景
- 数据结构相对稳定,但对其操作经常扩展的系统。
- 编译器设计中用于遍历语法树。
- 报表生成、日志记录、渲染引擎等需统一处理多种对象的场景。
Java中的典型应用
- Java编译器工具(如javac)使用访问者模式遍历AST(抽象语法树).
- XML/JSON解析框架中对节点进行统一访问处理。
- Spring框架中用于配置解析和依赖注入的访问逻辑。
变体与替代方案
- 双亲派(Double Dispatch): 访问者模式的核心机制。
- 策略模式: 时和单一结构多算法,但不具备访问者对多种元素的支持能力。
- 责任链模式: 侧重请求传递而非统一访问。