Apply Now Apply Now Apply Now
header_logo
Post thumbnail
SOFTWARE DEVELOPMENT

Visitor Method Design Pattern: A Beginner’s Guide

By Jebasta

Imagine a tax inspector who visits different types of properties: houses, shops, and factories. Each property type is taxed differently. The inspector does not change the properties. The properties do not change either. The inspector simply visits each one and applies the right calculation based on what it is.

That is the Visitor Method Design Pattern in a nutshell. You have a collection of objects. You want to perform an operation on each one. But the operation differs depending on the type of object. Instead of stuffing that logic inside each object, you pull it out into a separate Visitor class that travels through the collection and handles each type.

Quick Answer

The Visitor Method Design Pattern lets you add new operations to a group of objects without changing the objects themselves. You create a Visitor class that knows how to handle each type of object. Each object accepts the visitor and lets it do its work. The objects stay clean. All new logic lives in the visitor.

Table of contents


  1. What is the Visitor Method Design Pattern?
  2. How the Visitor Method Design Pattern Works: Step by Step
    • Step 1: Create the Visitor Interface
    • Step 2: Create the Element Interface
    • Step 3: Create the Concrete Elements
    • Step 4: Create a Concrete Visitor
    • Step 5: Put It All Together
  3. Adding a New Operation Without Touching the Elements
  4. A Real Example: Shopping Cart
  5. When to Use the Visitor Method Design Pattern
  6. When NOT to Use the Visitor Method Design Pattern
  7. Quick Reference: The 4 Parts
  8. Tips for Using the Visitor Method Design Pattern
    • 💡 Did You Know?
  9. Conclusion
  10. FAQs
    • What is double dispatch in the Visitor Method Design Pattern?
    • What is the difference between Visitor and Strategy patterns?
    • Can I use the Visitor Method Design Pattern in JavaScript?
    • Is the Visitor pattern difficult to implement?
    • What happens when I add a new element type?

What is the Visitor Method Design Pattern?

The Visitor Method Design Pattern is a behavioral design pattern. Behavioral patterns are about how objects communicate and share responsibility.

Here is the core problem it solves. You have several classes. You want to add a new operation across all of them. The traditional way is to add a new method to every class. That means touching every class every time a new operation is needed. If you have five classes and three new operations, that is fifteen changes spread across your codebase.

The Visitor Method Design Pattern solves this by doing one thing differently: instead of adding the operation to each class, you create one new Visitor class that contains all the logic for that operation.

The four parts of the Visitor Method Design Pattern:

  • Visitor: The class that contains the operation logic. Has one method per object type it can visit.
  • Concrete Visitor: A specific implementation of the visitor (tax calculator, export tool, report generator)
  • Element: The interface that all visitable objects implement. Has one method: accept(visitor)
  • Concrete Element: The actual objects being visited (House, Shop, Factory)

Do check out the HCL GUVI AI Software Development Course if you want to master advanced software engineering concepts like the Visitor Method Design Pattern with real-world coding practice. This industry-focused program covers design patterns, system design, backend development, AI-powered applications, and scalable software architecture through hands-on projects, live mentoring, and certifications from IITM Pravartak and MongoDB, helping you become job-ready for modern developer roles. 

How the Visitor Method Design Pattern Works: Step by Step

Step 1: Create the Visitor Interface

The Visitor interface declares one visit() method for each type of element it can visit.

Python code

class Visitor:
    def visit_house(self, house):
        pass

    def visit_shop(self, shop):
        pass

    def visit_factory(self, factory):
        pass

One method per element type. Each method receives the element it is visiting.

Step 2: Create the Element Interface

Every object that can be visited must implement accept(). This method receives a visitor and calls the right visit method on it.

Python code

class Element:
    def accept(self, visitor: Visitor):
        pass

This is the key step. The element calls the visitor. This is called double dispatch, which means the right method is chosen based on both the visitor type and the element type.

Step 3: Create the Concrete Elements

These are the actual objects being visited. Each one calls the correct visit() method on the visitor.

Python code

class House(Element):
    def __init__(self, area):
        self.area = area

    def accept(self, visitor):
        visitor.visit_house(self)   # tells visitor: I am a House

class Shop(Element):
    def __init__(self, revenue):
        self.revenue = revenue

    def accept(self, visitor):
        visitor.visit_shop(self)    # tells visitor: I am a Shop

class Factory(Element):
    def __init__(self, workers):
        self.workers = workers

    def accept(self, visitor):
        visitor.visit_factory(self) # tells visitor: I am a Factory

Each element knows only one thing: which visit method to call on the visitor. It does not know what the visitor does.

MDN

Step 4: Create a Concrete Visitor

Now write the actual operation. All the logic lives here, separated by element type.

Python code

class TaxCalculator(Visitor):
    def visit_house(self, house):
        tax = house.area * 10
        print(f"House tax: Rs. {tax}")

    def visit_shop(self, shop):
        tax = shop.revenue * 0.15
        print(f"Shop tax: Rs. {tax}")

    def visit_factory(self, factory):
        tax = factory.workers * 500
        print(f"Factory tax: Rs. {tax}")

All tax logic is in one class. The House, Shop, and Factory classes are untouched.

Step 5: Put It All Together

Python code

# Create elements
properties = [
    House(area=120),
    Shop(revenue=50000),
    Factory(workers=30)
]

# Create visitor
tax_inspector = TaxCalculator()

# Visit each element
for property in properties:
    property.accept(tax_inspector)

Output:

House tax: Rs. 1200
Shop tax: Rs. 7500.0
Factory tax: Rs. 15000

The visitor travels through each property and applies the right tax calculation. None of the property classes were changed.

Adding a New Operation Without Touching the Elements

This is where the Visitor Method Design Pattern pays off. Add a completely new operation by creating one new Visitor class. Zero changes to House, Shop, or Factory.

Python code

class PropertyReport(Visitor):
    def visit_house(self, house):
        print(f"House report: {house.area} sqm residential property")

    def visit_shop(self, shop):
        print(f"Shop report: Revenue of Rs. {shop.revenue}")

    def visit_factory(self, factory):
        print(f"Factory report: Employs {factory.workers} workers")

# Same elements, new visitor
reporter = PropertyReport()
for property in properties:
    property.accept(reporter)

Output:

House report: 120 sqm residential property
Shop report: Revenue of Rs. 50000
Factory report: Employs 30 workers

New operation. One new class. Nothing else changed. This is the core value of the Visitor Method Design Pattern.

Riddle: You have a shopping cart with three item types: Book, Electronics, and Clothing. You need to calculate the total price, apply discounts, and generate an invoice. Without the Visitor Method Design Pattern, how many methods do you add across all classes? With it, how many classes do you add?

Answer: Without the visitor: 3 methods × 3 classes = 9 changes across your codebase. With the Visitor Method Design Pattern: 3 new Visitor classes, zero changes to Book, Electronics, or Clothing. Every future operation is also one new class. The objects stay stable.

A Real Example: Shopping Cart

Here is a practical version using items in a shopping cart.

Python code

# Elements
class Book:
    def __init__(self, price):
        self.price = price

    def accept(self, visitor):
        visitor.visit_book(self)

class Electronics:
    def __init__(self, price):
        self.price = price

    def accept(self, visitor):
        visitor.visit_electronics(self)

class Clothing:
    def __init__(self, price):
        self.price = price

    def accept(self, visitor):
        visitor.visit_clothing(self)

# Visitor: calculates discounted price
class DiscountVisitor:
    def visit_book(self, book):
        print(f"Book: Rs. {book.price * 0.9:.0f} (10% off)")

    def visit_electronics(self, item):
        print(f"Electronics: Rs. {item.price * 0.85:.0f} (15% off)")

    def visit_clothing(self, item):
        print(f"Clothing: Rs. {item.price * 0.8:.0f} (20% off)")

# Usage
cart = [Book(500), Electronics(20000), Clothing(1200)]
discount = DiscountVisitor()

for item in cart:
    item.accept(discount)

Output:

Book: Rs. 450 (10% off)
Electronics: Rs. 17000 (15% off)
Clothing: Rs. 960 (20% off)

Each item type gets its own discount rule. Adding a new item type (like FoodItem) means adding one new visit_food() method to existing visitors. Adding a new operation (like tax calculation) means creating one new Visitor class.

When to Use the Visitor Method Design Pattern

  • When you need to add operations to a stable set of classes without modifying them
  • When an operation spans many unrelated classes and you do not want to scatter that logic across all of them
  • When you have many distinct operations on the same group of objects (tax, audit, export, report, print)
  • Compilers and interpreters: Each node in an abstract syntax tree (AST) accepts visitors for type checking, code generation, and optimisation
  • Document export systems: A document tree accepts an HTML visitor, a PDF visitor, or a Markdown visitor without the nodes knowing the format

When NOT to Use the Visitor Method Design Pattern

  • When your element classes change frequently: Every time you add a new element type, you must update every existing Visitor class to add the new visit method. If the object structure is unstable, the pattern creates more work than it saves.
  • When there is only one operation: If you only ever need to do one thing to your objects, the Visitor Method Design Pattern is overkill.
  • When objects are simple: A small flat list of similar objects does not need the visitor structure.

Quick Reference: The 4 Parts

PartRoleIn the Tax Example
Visitor interfaceDeclares one visit method per element typeVisitor with visit_house, visit_shop, visit_factory
Concrete VisitorImplements the actual operationTaxCalculator, PropertyReport
Element interfaceDeclares the accept(visitor) methodElement base class
Concrete ElementCalls the right visit method on the visitorHouse, Shop, Factory

Tips for Using the Visitor Method Design Pattern

  • Use it when your objects are stable but operations keep growing: If new classes get added often, consider a different approach. The Visitor Method Design Pattern works best when the element types are fixed.
  • Name your visitors clearly: TaxCalculator, InvoiceGenerator, XMLExporter are clear. Visitor1 is not. Clear names make your visitor list self-documenting.
  • Keep each visitor focused on one operation: One visitor should do one thing. Do not combine tax calculation and report generation in the same visitor class.
  • Accept can be one line: The accept() method in every element is always one line: call the right visit method on the visitor and pass self. Keep it exactly that simple.

💡 Did You Know?

  • Compilers use the Visitor Method Design Pattern heavily. When a compiler processes your code, it builds a tree of nodes (AST). Visitors then travel through that tree to perform type checking, dead code elimination, and code generation without the tree nodes knowing any of those details.
  • The Visitor Method Design Pattern is sometimes called the “open-closed principle in action” because it lets you add new operations (open for extension) without modifying existing classes (closed for modification).

Conclusion

The Visitor Method Design Pattern gives you a clean way to add new operations to a group of objects without touching those objects. The objects stay focused on what they are. All new behaviour lives in separate Visitor classes that you can add, remove, or swap freely.

The pattern has four parts: the Visitor interface, the Concrete Visitors that implement operations, the Elements that accept visitors, and the Client that connects them. Once you understand those four parts, the Visitor Method Design Pattern becomes one of the clearest ways to extend a system without breaking what already works.

Start with the tax inspector example. Then try adding your own visitor to the shopping cart. The pattern becomes natural very quickly.

FAQs

1. What is double dispatch in the Visitor Method Design Pattern?

Double dispatch means the right method is chosen based on two types: the visitor type and the element type. When an element calls visitor.visit_house(self), the language picks the method based on both the visitor class and the fact that self is a House. This is how the Visitor Method Design Pattern routes each element to the correct logic automatically.

2. What is the difference between Visitor and Strategy patterns?

Strategy swaps one algorithm for another on the same object. Visitor applies different logic to different object types in a collection. Strategy is about choosing how one thing is done. Visitor is about applying the right operation to each type in a group.

3. Can I use the Visitor Method Design Pattern in JavaScript?

Yes. Create a Visitor object with one method per element type. Each element class has an accept(visitor) method that calls the right visitor method and passes itself. The pattern works the same in JavaScript, TypeScript, Java, and C#.

4. Is the Visitor pattern difficult to implement?

No. The hardest part to understand is the accept() method. Once you see that it just calls visitor.visit_this_type(self), everything else follows naturally. The tax calculator and shopping cart examples in this guide are under 30 lines each.

MDN

5. What happens when I add a new element type?

Every existing Visitor class must add a new visit method for the new type. This is the main trade-off of the Visitor Method Design Pattern. It is easy to add new operations but harder to add new element types. This is why the pattern works best when your element types are stable.

Success Stories

Did you enjoy this article?

Schedule 1:1 free counselling

Similar Articles

Loading...
Get in Touch
Chat on Whatsapp
Request Callback
Share logo Copy link
Table of contents Table of contents
Table of contents Articles
Close button

  1. What is the Visitor Method Design Pattern?
  2. How the Visitor Method Design Pattern Works: Step by Step
    • Step 1: Create the Visitor Interface
    • Step 2: Create the Element Interface
    • Step 3: Create the Concrete Elements
    • Step 4: Create a Concrete Visitor
    • Step 5: Put It All Together
  3. Adding a New Operation Without Touching the Elements
  4. A Real Example: Shopping Cart
  5. When to Use the Visitor Method Design Pattern
  6. When NOT to Use the Visitor Method Design Pattern
  7. Quick Reference: The 4 Parts
  8. Tips for Using the Visitor Method Design Pattern
    • 💡 Did You Know?
  9. Conclusion
  10. FAQs
    • What is double dispatch in the Visitor Method Design Pattern?
    • What is the difference between Visitor and Strategy patterns?
    • Can I use the Visitor Method Design Pattern in JavaScript?
    • Is the Visitor pattern difficult to implement?
    • What happens when I add a new element type?