Behavioral

Visitor

Visitor moves an operation out of the classes it acts on and into its own class, so new operations can be added to a fixed set of element types without touching those types at all.

Complexity
Popularity

Problem

Imagine you maintain an object structure representing a geometric scene: dots, circles, and rectangles. Now the team needs to export the whole scene to XML.

You could add an `exportToXml` method to every shape class. But XML export is only the beginning - next comes JSON export, area calculation, and bounding-box computation. Each new operation forces you to edit every shape class, mixing unrelated concerns into classes that should only model geometry.

Worse, these operations often need behavior specific to each concrete type, so a single generic method on a common base class won't do. You need a way to add new type-specific operations to a class hierarchy without repeatedly cracking it open.

Solution

The Visitor pattern suggests placing the new behavior into a separate class called a visitor, instead of trying to integrate it into existing classes. The object structure that originally had to perform the behavior is now passed to the visitor's methods so the behavior can access the data it needs.

The visitor declares a set of visiting methods - one per concrete element type (`visitCircle`, `visitRectangle`, and so on). To route a call to the correct method, each element class implements a single `accept(visitor)` method that calls back the visitor method matching its own type. This technique is called double dispatch: the operation executed depends on both the element type and the visitor type.

Adding a new operation now means writing one new visitor class, without touching any element. The element hierarchy stays closed for modification while remaining open for new operations.

When to Use

  • Reach for Visitor when you need to run several unrelated operations over every node of a stable object structure, such as a tree.
  • It also helps pull occasional, auxiliary behavior - export, validation, reporting - out of core domain classes so those classes can stay focused on their main responsibility.
  • Use it when an operation is only meaningful for some of the classes in a hierarchy, since a visitor can implement just the visit methods that apply.

Real-World Examples

  • **Compilers** - a visitor walks the abstract syntax tree to perform type checking, optimization, and code generation as separate passes over the same node types.
  • **Document exporters** - a rich document model is traversed by different visitors to render it to HTML, PDF, or plain text without changing the document classes.
  • **Shopping cart pricing** - visitors compute totals, taxes, and discounts across a mix of item types (books, electronics, groceries) each with its own rules.