Full Stack • Java • System Design • Cloud • AI Engineering

Visitor Design Pattern in Java

Learn Visitor Design Pattern in Java with double dispatch, object structure traversal, reporting systems, tax calculation engines, AST processing, enterprise use cases, UML diagrams, and interview questions.

What You Will Learn

  • What is Visitor Pattern?
  • Why Visitor Pattern is Needed
  • Double Dispatch Explained
  • Object Structure Traversal
  • Reporting Engine Example
  • Tax Calculation Example
  • Java Implementation
  • Enterprise Use Cases
  • Benefits and Limitations
  • Interview Questions

Introduction

Imagine an e-commerce system contains:

Product

Book

Laptop

Mobile

Furniture

Now business asks for:

Tax Calculation

Discount Calculation

Report Generation

Export To PDF

Export To Excel

Without Visitor Pattern:

class Book {

   calculateTax();

   generateReport();

   exportPdf();

   exportExcel();
}

Every time a new operation is added:

Modify All Classes

This violates:

Open Closed Principle

Visitor Pattern solves this problem.


What is Visitor Pattern?

Visitor is a Behavioral Design Pattern that lets you add new operations to existing object structures without modifying those structures.

Simple View:

Object Structure

↓

Visitor

↓

Operation

Purpose of Visitor Pattern

Primary Goal:

Add New Operations

Without Modifying Existing Classes

Real World Analogy

Think about a hospital.

Patients:

Adult Patient

Child Patient

Senior Patient

Visitors:

Doctor

Nurse

Insurance Auditor

Each visitor performs different operations on the same patient.


Problem Without Visitor

flowchart LR
    A[Book]
    B[Laptop]
    C[Mobile]

    A --> D[Tax Logic]
    B --> D
    C --> D

    A --> E[Report Logic]
    B --> E
    C --> E

Every class contains every operation.

Hard to maintain.


Solution With Visitor

flowchart LR
    A[Book]
    B[Laptop]
    C[Mobile]

    D[Tax Visitor]
    E[Report Visitor]

    D --> A
    D --> B
    D --> C

    E --> A
    E --> B
    E --> C

Operations move into visitors.


Visitor Architecture

flowchart LR
    A[Element]
    B[Visitor]

    A --> B

Key Components

Visitor

Defines operations.


Concrete Visitor

Implements operations.


Element

Accepts visitors.


Object Structure

Collection of elements.


UML Diagram

classDiagram

class Visitor {
    +visit(Book)
    +visit(Laptop)
}

class TaxVisitor
class ReportVisitor

class Product {
    +accept()
}

class Book
class Laptop

Visitor <|.. TaxVisitor
Visitor <|.. ReportVisitor

Product <|-- Book
Product <|-- Laptop

Example Scenario

Products:

Book

Laptop

Operations:

Calculate Tax

Generate Report

Step 1: Visitor Interface

public interface Visitor {

    void visit(Book book);

    void visit(Laptop laptop);
}

Step 2: Product Interface

public interface Product {

    void accept(
            Visitor visitor);
}

Step 3: Book Class

public class Book
        implements Product {

    private double price;

    public Book(
            double price) {

        this.price = price;
    }

    public double getPrice() {

        return price;
    }

    @Override
    public void accept(
            Visitor visitor) {

        visitor.visit(this);
    }
}

Step 4: Laptop Class

public class Laptop
        implements Product {

    private double price;

    public Laptop(
            double price) {

        this.price = price;
    }

    public double getPrice() {

        return price;
    }

    @Override
    public void accept(
            Visitor visitor) {

        visitor.visit(this);
    }
}

Step 5: Tax Visitor

public class TaxVisitor
        implements Visitor {

    @Override
    public void visit(
            Book book) {

        System.out.println(
                "Book Tax: "
                + book.getPrice() * 0.05);
    }

    @Override
    public void visit(
            Laptop laptop) {

        System.out.println(
                "Laptop Tax: "
                + laptop.getPrice() * 0.18);
    }
}

Step 6: Report Visitor

public class ReportVisitor
        implements Visitor {

    @Override
    public void visit(
            Book book) {

        System.out.println(
                "Book Report Generated");
    }

    @Override
    public void visit(
            Laptop laptop) {

        System.out.println(
                "Laptop Report Generated");
    }
}

Step 7: Client

public class VisitorDemo {

    public static void main(
            String[] args) {

        Product book =
                new Book(100);

        Product laptop =
                new Laptop(1000);

        Visitor taxVisitor =
                new TaxVisitor();

        Visitor reportVisitor =
                new ReportVisitor();

        book.accept(taxVisitor);
        laptop.accept(taxVisitor);

        book.accept(reportVisitor);
        laptop.accept(reportVisitor);
    }
}

Output

Book Tax: 5.0

Laptop Tax: 180.0

Book Report Generated

Laptop Report Generated

Execution Flow

flowchart LR
    A[Product]
    B[Accept Visitor]
    C[Visitor Operation]
    D[Result]

    A --> B
    B --> C
    C --> D

Double Dispatch Explained

Visitor Pattern uses:

Double Dispatch

Normal Java:

object.method();

Single dispatch.

Visitor:

visitor.visit(book);

Runtime determines:

Visitor Type

+

Element Type

This is called:

Double Dispatch

Double Dispatch Flow

flowchart LR
    A[Visitor]
    B[Book]
    C[Visit Method]

    A --> C
    B --> C

Tax Calculation Example

Products:

Book

Laptop

Mobile

Different tax rates.


Tax Engine Architecture

flowchart LR
    A[Product]
    B[Tax Visitor]
    C[Tax Result]

    A --> B
    B --> C

Reporting System Example

Generate:

PDF Report

Excel Report

CSV Report

without modifying Product classes.


Reporting Flow

flowchart LR
    A[Product]
    B[Report Visitor]
    C[PDF]
    D[Excel]
    E[CSV]

    B --> C
    B --> D
    B --> E

    A --> B

Banking Example

Account Types:

Savings

Current

Loan

Visitors:

Interest Calculator

Risk Analyzer

Audit Report

Banking Workflow

flowchart LR
    A[Savings]
    B[Current]
    C[Loan]

    D[Interest Visitor]

    D --> A
    D --> B
    D --> C

Insurance Example

Policies:

Health

Vehicle

Life

Visitors:

Premium Calculator

Claim Auditor

Risk Analyzer

Insurance Architecture

flowchart LR
    A[Policy]
    B[Premium Visitor]
    C[Risk Visitor]

    A --> B
    A --> C

Compiler Example

Visitor is heavily used in:

AST Processing

Code Analysis

Compilers

Parsers

AST Traversal

flowchart LR
    A[AST Node]
    B[Visitor]
    C[Code Generation]

    A --> B
    B --> C

Enterprise Examples

Banking

Interest Calculation

Risk Assessment

Audit Reporting

Insurance

Premium Calculation

Fraud Analysis

Claim Reporting

Retail

Tax Calculation

Invoice Generation

Discount Reports

Compiler Systems

AST Traversal

Optimization

Code Generation

Spring Framework Examples

Common Visitor-like implementations:

BeanPostProcessor

HandlerMethodArgumentResolver

Jackson Object Traversal

AST Visitors

Benefits

✅ Open Closed Principle

✅ Easy To Add New Operations

✅ Centralized Logic

✅ Cleaner Domain Objects

✅ Excellent For Reporting Systems

✅ Supports Complex Object Structures


Limitations

❌ Adding New Element Types Is Hard

❌ More Classes

❌ Increased Complexity

❌ Tight Coupling Between Visitor And Elements


When To Use

Use Visitor Pattern when:

  • Object structure is stable
  • New operations are added frequently
  • Reporting systems exist
  • Tax calculations vary
  • AST traversal is needed

When Not To Use

Avoid when:

  • Element types change frequently
  • Object structure is unstable

Visitor vs Strategy

Feature Visitor Strategy
Purpose Add Operations Change Algorithm
Focus Object Structure Behavior
Uses Double Dispatch Yes No

Visitor vs Decorator

Feature Visitor Decorator
Goal Add Operations Add Behavior
Modifies Object No Yes
Focus External Processing Runtime Enhancement

Real Enterprise Architecture

flowchart LR
    A[Domain Objects]
    B[Visitor Engine]
    C[Reports]
    D[Tax Calculation]
    E[Analytics]

    A --> B
    B --> C
    B --> D
    B --> E

Interview Questions

What is Visitor Pattern?

A behavioral pattern that allows adding new operations without modifying existing object structures.


Main Components?

Visitor

Concrete Visitor

Element

Object Structure

What is Double Dispatch?

Method execution based on both visitor type and element type.


Real World Example?

Tax Calculation Engine.


Enterprise Example?

Reporting Systems and AST Processing.


Main Benefit?

Adding new operations without changing domain classes.


Key Takeaways

  • Visitor is a Behavioral Design Pattern.
  • Separates operations from object structures.
  • Uses Double Dispatch.
  • Excellent for Reporting, Tax Calculation, and AST Processing.
  • Follows Open Closed Principle.
  • Common in Banking, Insurance, Retail, and Compiler Systems.
  • Best when object structure is stable but operations change frequently.

Design Patterns Series Completed

Creational Patterns

  • Singleton
  • Factory Method
  • Abstract Factory
  • Builder
  • Prototype

Structural Patterns

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy

Behavioral Patterns

  • Chain Of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Template Method
  • Visitor