Visitor Pattern
Represent an operation to be performed on elements of an object structure — define new operations without changing element classes.
📌 Key IdeaEach Element implements
accept(Visitor v) → calls v.visitConcrete(this) (double dispatch). Add new visitor class for new operation over stable structure (AST walkers, document exports). Trade-off: adding new element type touches every visitor.Visual
👤 Double dispatch
for (Node n : tree)
n.accept(visitor); // Node calls visitor.visit(this)
class PrintVisitor implements Visitor {
void visit(PlusExpr e) { ... }
void visit(LiteralExpr e) { ... }
}Operations live in visitors — structure classes stay slim.
When to Use
- Stable object structure (AST, scene graph) but many orthogonal operations (pretty-print, eval, compile).
- You want to keep node classes small — behaviour grouped by visitor.
When NOT to Use
- Structure churns frequently — each new node type updates all visitors (opposite trade-off to abstract factory pain).
- Simple iteration — Iterator / Stream suffices.
Anti-Pattern (What NOT to Do)
One
eval with instanceof ladderBadjavaint eval(Expr e) {
if (e instanceof Literal l) return l.v();
if (e instanceof Add a) return eval(a.left()) + eval(a.right());
throw new UnsupportedOperationException();
}Adding
Mul edits this method — open/closed violation.The Right Way
Visitor — new op = new classGoodjava
interface Expr {
<T> T accept(ExprVisitor<T> v);
}
interface ExprVisitor<T> {
T visit(Literal e);
T visit(Add e);
}
class EvalVisitor implements ExprVisitor<Integer> {
public Integer visit(Literal e) { return e.v(); }
public Integer visit(Add e) {
return e.left().accept(this) + e.right().accept(this);
}
}New traversal (
PrintVisitor) doesn't touch Literal / Add classes.Pros & Cons
👍 Pros
- Groups related behaviour across types (
XmlExportVisitor). - Accumulates state in visitor fields during traversal.
👎 Cons
- Adding new element type forces changes across visitors.
- Indirection — double dispatch unfamiliar to some readers.
Common Confusions Cleared Up
Visitor vs Iterator
Iterator walks structure without knowing node-specific operations. Visitor performs typed operations per node via visit overloads.
Interview Q&A
Likely Follow-up Questions
- Acyclic Visitor variant — when would you use it?
Quick Cheat Sheet
IntentNew ops over stable structure.
Mechanism
accept + visit overloads.Trade-offOps easy; new node type costly.