Visitor Pattern
Also Known As
double dispatch
TL;DR
A behavioural pattern that separates an algorithm from the objects it operates on — adding new operations to a class hierarchy without modifying those classes.
Explanation
The Visitor pattern uses double dispatch: the object calls accept(visitor), which calls visitor.visit(this). This allows adding new operations to a stable class hierarchy by writing new Visitor classes rather than adding methods to each node. Common uses: abstract syntax tree traversal, serialisation to different formats, static analysis tools, and document export. The trade-off: adding a new node type requires updating all existing visitors.
Common Misconception
✗ Visitor requires modifying the visited classes — each class only needs one accept(VisitorInterface $v) method added once; all future operations are new Visitor implementations.
Why It Matters
Visitor allows adding new operations to a closed class hierarchy without modifying it — ideal for compilers, AST processors, and document renderers where operations change but the node types are stable.
Common Mistakes
- Using Visitor when the class hierarchy changes frequently — each new class requires updating all visitors, which is more painful than adding a method to each class.
- Not defining a VisitorInterface — without it, the pattern provides no type safety.
- Confusing Visitor (new operations, stable classes) with Strategy (interchangeable algorithms, single class).
- Implementing Visitor for simple trees where a recursive method on each node is simpler.
Code Examples
✗ Vulnerable
// Without visitor — adding export requires modifying every node:
class TextNode {
public function toHtml(): string { /* ... */ }
public function toPdf(): string { /* ... */ } // Must add to every node class
public function toMarkdown(): string { /* ... */ } // Keeps growing
}
✓ Fixed
// Visitor — add new export format without touching node classes:
interface NodeVisitor {
public function visitText(TextNode $node): string;
public function visitImage(ImageNode $node): string;
}
class TextNode {
public function accept(NodeVisitor $v): string { return $v->visitText($this); }
}
class MarkdownExporter implements NodeVisitor {
public function visitText(TextNode $n): string { return $n->content; }
public function visitImage(ImageNode $n): string { return ""; }
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
20
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 7
Perplexity 2
Ahrefs 2
Unknown AI 2
Google 2
ChatGPT 2
Also referenced
How they use it
crawler 15
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: High
⚡ Quick Fix
Use Visitor when you need to add new operations to a class hierarchy without modifying those classes — define accept() in each element, implement the operation in a Visitor class
📦 Applies To
PHP 5.0+
web
cli
🔗 Prerequisites
🔍 Detection Hints
New operation requires modifying every class in a hierarchy; instanceof checks to apply different behaviour per type
Auto-detectable:
✗ No
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: Class
Tests: Update