Visitor
Add new operations to an existing class hierarchy without modifying those classes β the Visitor carries the new behavior and visits each element.
Intent & Description
π― Intent
Separate operations from the objects they operate on so you can add new operations without touching the class hierarchy.
π Context
You have a document tree (paragraphs, images, tables, headings) and you keep needing to add new operations: XML export, HTML export, word count, accessibility audit. Adding a new method to every node class every time is a maintenance nightmare.
π‘ Solution
Each element class has an accept(visitor) method that just calls visitor.visitElement(this). Visitors implement a visit method for each element type. To add a new operation, write a new Visitor class β zero changes to the element hierarchy.
Real-world Use Case
Source
π TL;DR
Elements accept Visitors. Visitors do the work. New operation = new Visitor class, no element changes. Only works well when the element hierarchy rarely changes.
Advantages
- New operations are new Visitor classes β existing elements are untouched.
- Related behavior for multiple types is co-located in one Visitor class.
Disadvantages
- Adding or removing a class from the hierarchy requires updating every Visitor β the element hierarchy needs to be stable.
class Shape {
accept(visitor) {}
}
class Dot extends Shape {
accept(visitor) { visitor.visitDot(this); }
}
class XMLExportVisitor {
visitDot(dot) { console.log("Exporting dot as XML"); }
}