访问者 (Visitor)
访问者 (Visitor) 是一种行为型设计模式,将算法与所操作的对象结构分离,使得在不修改各元素类的前提下定义作用于这些元素的新操作。适合“结构稳定、操作常变”的场景。
- 对象结构(如 AST、文档节点)相对稳定,但需要经常增加针对这些元素的新操作;若在每个元素类里加方法会不断修改元素类。
- 希望新操作能集中定义、便于扩展,而不改动元素类。
- 元素 (Element):定义
accept(Visitor v),在 accept 内调用v.visit(this),把自身交给访问者。 - 具体元素 (ConcreteElement):实现 accept,访问者通过多态对不同类型的元素执行不同逻辑。
- 访问者 (Visitor):为每种具体元素声明
visit(ConcreteElementA)、visit(ConcreteElementB)等,实现针对该元素的操作。 - 具体访问者:实现各 visit 方法,完成具体算法。客户端创建访问者并让元素接受访问,遍历结构时对每个元素调用
accept(visitor)。
classDiagram
class Element {
<<interface>>
+accept(Visitor v)* void
}
class ConcreteElementA {
+accept(Visitor v) void
}
class Visitor {
<<interface>>
+visit(ConcreteElementA e)* void
+visit(ConcreteElementB e)* void
}
class ConcreteVisitor {
+visit(ConcreteElementA e) void
+visit(ConcreteElementB e) void
}
Element <|.. ConcreteElementA
Visitor <|.. ConcreteVisitor
ConcreteElementA ..> Visitor : accept
Java 示例
Section titled “Java 示例”public interface Element { void accept(Visitor v);}
public class ConcreteElementA implements Element { @Override public void accept(Visitor v) { v.visit(this); }}
public interface Visitor { void visit(ConcreteElementA e);}
public class ConcreteVisitor implements Visitor { @Override public void visit(ConcreteElementA e) { System.out.println("Visitor 访问 ConcreteElementA"); }}
Element el = new ConcreteElementA();el.accept(new ConcreteVisitor()); // 输出: Visitor 访问 ConcreteElementA访问者把“对结构的操作”从元素中抽离到访问者中,便于增加新操作而不改元素类;代价是增加新元素类型需改访问者接口,适合元素类型稳定、操作多变的场景。