# Visitor Pattern

The Visitor Pattern is a behavioral design pattern that lets you separate algorithms from the objects on which they operate. It allows you to add new operations to existing object structures without modifying the structures.

## 1. The Core Concept

The pattern suggests that you place the new behavior into a separate class called a **Visitor**, instead of trying to integrate it into existing classes. The original object that has to perform the behavior is now passed to one of the visitor's methods as an argument.

*   **Double Dispatch:** The pattern relies on a technique called Double Dispatch. The object "accepts" a visitor, and tells the visitor to "visit" itself.
    1.  Client calls `element.accept(visitor)`.
    2.  Element calls `visitor.visitElement(this)`.

## 2. Analogy: Insurance Agent

Imagine an insurance agent visiting different types of buildings.
*   **Elements:** House, Bank, Factory.
*   **Visitor:** Insurance Agent.
*   **Operation:** Selling insurance.

The logic for selling insurance to a Bank is different from selling to a Factory. Instead of adding a `sellInsurance()` method to the `Bank` and `Factory` classes (polluting them), the Agent knows how to handle each type. The building just "accepts" the agent.

## 3. Example (TypeScript)

Let's say we have shapes, and we want to export them to XML.

```typescript
// The Element Interface
interface Shape {
    accept(visitor: Visitor): void;
}

// Concrete Element 1
class Circle implements Shape {
    constructor(public radius: number) {}

    accept(visitor: Visitor): void {
        visitor.visitCircle(this);
    }
}

// Concrete Element 2
class Square implements Shape {
    constructor(public side: number) {}

    accept(visitor: Visitor): void {
        visitor.visitSquare(this);
    }
}

// The Visitor Interface
interface Visitor {
    visitCircle(element: Circle): void;
    visitSquare(element: Square): void;
}

// Concrete Visitor
class XMLExportVisitor implements Visitor {
    visitCircle(element: Circle): void {
        console.log(`<circle><radius>${element.radius}</radius></circle>`);
    }

    visitSquare(element: Square): void {
        console.log(`<square><side>${element.side}</side></square>`);
    }
}

// Usage
const shapes: Shape[] = [
    new Circle(5),
    new Square(10)
];

const exportVisitor = new XMLExportVisitor();

for (const shape of shapes) {
    shape.accept(exportVisitor);
}
// Output:
// <circle><radius>5</radius></circle>
// <square><side>10</side></square>
```

## 4. Pros and Cons

| Pros | Cons |
| :--- | :--- |
| **Open/Closed Principle:** You can introduce a new behavior (Visitor) without changing the classes of the elements. | **Updating Hierarchy:** If you add a new Element class (e.g., `Triangle`), you must update the Visitor interface and *all* concrete visitors. |
| **Single Responsibility:** A visitor gathers related operations into a single class. | **Encapsulation:** Visitors might need access to the private fields of elements to do their job. |
| **Accumulating State:** Visitors can accumulate state as they traverse the object structure. | |

## 5. Double Dispatch Explained

Double Dispatch is a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call.

In most languages (like Java, C#, C++), method overloading is static (compile-time).
*   `visitor.visit(element)`: The compiler decides which `visit` method to call based on the *static* type of `element`. If `element` is declared as `Shape` but is actually a `Circle`, the compiler still looks for `visit(Shape)`.

To solve this, the Visitor pattern uses two calls:
1.  **First Dispatch:** `element.accept(visitor)`. This is polymorphic. The runtime calls the `accept` method of the actual class of `element` (e.g., `Circle.accept`).
2.  **Second Dispatch:** Inside `Circle.accept`, we call `visitor.visitCircle(this)`. Now the compiler knows `this` is a `Circle`, so it binds to the correct method on the visitor.

This trick allows the program to select the correct method based on the types of *both* the element and the visitor.

[[programming/design-patterns]]
[[programming/object-oriented-programming]]