What if you could add new features without rewriting your whole code every time?
Why Visitor pattern in LLD? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a collection of different shapes like circles, squares, and triangles. You want to perform various operations on them, such as calculating area, drawing, or exporting data. Doing this manually means writing separate code for each shape and each operation, mixing all logic together.
This manual approach quickly becomes messy and hard to maintain. Every time you add a new operation, you must change all shape classes. This leads to duplicated code, errors, and lots of time spent updating multiple places.
The Visitor pattern lets you separate operations from the objects they work on. You create visitor classes for each operation and let shapes accept visitors. This way, you add new operations without changing shape classes, keeping code clean and easy to extend.
class Circle { double area() { ... } void draw() { ... } } class Square { double area() { ... } void draw() { ... } }
interface Visitor { void visitCircle(Circle c); void visitSquare(Square s); }
class AreaVisitor implements Visitor { ... }
class DrawVisitor implements Visitor { ... }
class Circle { void accept(Visitor v) { v.visitCircle(this); } }
class Square { void accept(Visitor v) { v.visitSquare(this); } }You can add new operations easily without touching existing shape code, making your system flexible and maintainable.
In a graphic editor, you can add new features like exporting shapes to different formats or applying filters by just creating new visitors, without changing the shape classes.
Separates operations from object structures.
Makes adding new operations easy and safe.
Keeps code organized and maintainable.
Practice
Visitor pattern in system design?Solution
Step 1: Understand the Visitor pattern concept
The Visitor pattern allows defining new operations on objects without changing their classes.Step 2: Identify the main goal
Its main goal is to separate the operation logic from the object structure to keep code flexible.Final Answer:
To separate operations from the objects on which they operate -> Option AQuick Check:
Visitor pattern = separates operations [OK]
- Confusing Visitor with Singleton pattern
- Thinking it creates object instances
- Assuming it controls access permissions
ElementA?Solution
Step 1: Recall Visitor interface method naming
The visitor interface defines methods namedvisitwith the element type as parameter.Step 2: Match correct signature
The correct signature isvoid visit(ElementA element);to visitElementA.Final Answer:
void visit(ElementA element); -> Option DQuick Check:
Visitor method = visit(Element) [OK]
- Confusing accept and visit method names
- Using no parameters in visit method
- Swapping visitor and element in parameters
class ElementA {
accept(visitor) {
visitor.visit(this);
}
}
class PrintVisitor {
visit(element) {
console.log('Visited element');
}
}
const element = new ElementA();
const visitor = new PrintVisitor();
element.accept(visitor);Solution
Step 1: Trace accept method call
Theacceptmethod callsvisitor.visit(this), passing the element instance.Step 2: Check visit method behavior
Thevisitmethod logs 'Visited element' to the console.Final Answer:
Visited element -> Option CQuick Check:
Visitor.visit logs message [OK]
- Expecting element type name in output
- Thinking visit method is missing
- Assuming no output without explicit return
class ElementB {
accept(visitor) {
visitor.accept(this);
}
}
class ConcreteVisitor {
visit(element) {
console.log('Visiting element');
}
}Solution
Step 1: Check accept method call
Theacceptmethod callsvisitor.accept(this), but visitor has noacceptmethod.Step 2: Identify correct visitor method
The visitor interface definesvisitmethods, soacceptshould callvisitor.visit(this).Final Answer:
ElementB calls visitor.accept instead of visitor.visit -> Option AQuick Check:
accept calls visit, not accept [OK]
- Confusing method names accept and visit
- Expecting accept to return a value
- Removing accept method from element
Solution
Step 1: Understand the problem of adding new operations
Modifying existing element classes is risky and breaks encapsulation.Step 2: Apply Visitor pattern solution
Create a new visitor class that implements the new operation for all element types, keeping element classes unchanged.Final Answer:
By creating a new visitor class implementing the operation for all element types -> Option BQuick Check:
Visitor adds operations via new visitor classes [OK]
- Modifying element classes directly
- Using inheritance to add operations
- Embedding operations as data in elements
