- Intent: Represent an operation to be performed on the elements of an object structure. Lets you define a new operation without changing the classes of the elements on which it operates.
Structure §
Image from: Gamma, Helm, Johnson, and Vissides
Applicability §
- An object structure contains many classes of objects with different interfaces and you want to perform operations on these objects that depend on their concrete classes.
- Many distinct and unrelated operations need to be performed in an object structure and you want to avoid polluting their classes with these operations.
- The classes defining the object structure rarely change but you often want to define new operations over the structure.
Consequences §
- Makes adding new operations easy.
- Gathers related operations and separates unrelated ones.
- Adding new element classes is hard.
- Allows traversing through class hierarchies
- Visitors can accumulate state as they visit each element.
- Breaks encapsulation.
Implementation §
Double Dispatch §
- Allows you to add operations without changing them. The operation that gets executed depends on the type of Visitor and the type of elements It visits.
Responsibility for Traversing Objects §
- Could be a function In the object structure
- Could be in the visitor (for complex traversals)
- Could be in a separate Iterator object