The Visitor Pattern falls under the Behavioral category.
Why? Because it is all about defining new operations on objects without changing their classes.
Say you have a VIP guest who can visit different rooms in a building. The guest behaves differently in each room, but instead of rewriting each room’s code, you just allow the guest to visit and decide what to do there.
Let's understand this with another example, diving deep this time.
The Document Processor
Imagine you are building an application that works with different types of documents - Word, PDF, and Spreadsheet.
You want to run operations like Spell check, Export to HTML, or Count words.
The Problem
If you add each new operation directly into the document classes, you will keep changing those classes every time. Overtime your classes would become messy, repetitive, and more importantly it breaks the Open/Closed Principle (classes should be open for extension, but closed for modification).
Enter the Visitor Pattern
The Visitor Pattern lets you add new operations without changing your document classes.
Each document has an Accept(visitor)
method. Its a way of saying
“Come in and do your work"
Each visitor knows exactly how to handle each document type.
What does the code look like?
//Step 1: Define the Visitor Interface
Interface DocumentVisitor
Method VisitWordDocument(wordDoc)
Method VisitPdfDocument(pdfDoc)
Method VisitSpreadsheet(sheet)
//Step 2: Define the Document Interface
Interface Document
Method Accept(visitor)
//Step 3: Concrete Document Classes
Class WordDocument implements Document
Method Accept(visitor)
visitor.VisitWordDocument(this)
Class PdfDocument implements Document
Method Accept(visitor)
visitor.VisitPdfDocument(this)
Class Spreadsheet implements Document
Method Accept(visitor)
visitor.VisitSpreadsheet(this)
//Step 4: Create Concrete Visitors (Operations)
Class SpellCheckVisitor implements DocumentVisitor
Method VisitWordDocument(wordDoc)
Print "Spell checking Word document..."
Method VisitPdfDocument(pdfDoc)
Print "Spell checking PDF document..."
Method VisitSpreadsheet(sheet)
Print "Spell checking Spreadsheet..."
Class ExportToHTMLVisitor implements DocumentVisitor
Method VisitWordDocument(wordDoc)
Print "Exporting Word document to HTML..."
Method VisitPdfDocument(pdfDoc)
Print "Exporting PDF document to HTML..."
Method VisitSpreadsheet(sheet)
Print "Exporting Spreadsheet to HTML..."
//caller logic
documents = [new WordDocument(), new PdfDocument(), new Spreadsheet()]
spellChecker = new SpellCheckVisitor()
exporter = new ExportToHTMLVisitor()
For each doc in documents
doc.Accept(spellChecker)
For each doc in documents
doc.Accept(exporter)
In our Document Processor example above, think of each visitor as a specialist.
SpellCheckVisitor
- knows how to spell check any document.
ExportToHTMLVisitor
- knows how to export any document to HTML.
When a document receives a visitor, it simply hands itself over, and says,
“Here is my PDF data. You know what to do.”
This way, you keep document classes simple. You can add new operations anytime without touching existing document classes. With this, your code stays clean, flexible, and easy to grow.
What Did We Achieve?
- No need to modify existing document classes when adding new operations.
- Operations (Visitors) are separated from the document structure.
- Adding a new visitor means adding new features without changing existing code.
When Should You Use Visitor Pattern?
- When you have a stable set of classes (like document types) but frequently add new operations.
- When you want to separate business logic from the object structure.
- When you need to perform many unrelated operations on objects without mixing those operations into the objects themselves.
Use Cases?
- Compilers: Different passes over syntax trees (type checking, optimization, code generation)
- File explorers: Performing operations on different file types
- Graphics editors: Applying different filters or transformations to shapes
- E-commerce: Running promotions or discounts on different product categories
Is Visitor Confused with Any Other Pattern?
Yes. It is sometimes mistaken for the Strategy Pattern. Both separate behavior from objects, but here is the difference,
Strategy: Object decides which behavior to use.
Visitor: External entity visits and applies behavior to the object.
To summarize, it would be apt to say,
Visitor Pattern is like inviting a VIP guest who knows exactly what to do in each room, without asking you to renovate the building every time they visit.
It offers great flexibility for adding new operations while keeping your object structure intact.
Hope you got a clear understanding of the Visitor Pattern!
Next up: Proxy Pattern. Let's meet there!
Top comments (0)