The Visitor pattern provides a maintainable, easy way to represent an operation to be performed on the elements of an object structure.
The Visitor pattern lets you define a new operation without changing the classes of the elements on which it operates. The figure below illustrates the Visitor pattern.
The following lists the benefits of using the Visitor pattern:
Makes adding new operations easy
Gathers related operations and separates unrelated ones
When to Use:
You should use the Visitor pattern when:
An object structure contains many classes of objects with differing interfaces and you want to perform operations on these objects that depend on their concrete classes.
Classes defining the object structure rarely change but you often want to define new operations over the structure.
Theory behind the Visitor Pattern
The Visitor pattern is useful in designing an operation across a heterogeneous collection of objects of a class hierarchy.
The Visitor pattern allows the operation to be defined without changing the class of any of the objects in the collection. To accomplish this, the Visitor pattern suggests defining the operation in
a separate class referred to as a visitor class. This separates the operation from the object collection that it operates on. For every new operation to be defined, a new visitor class is created.
Since the operation is to be performed across a set of objects, the visitor needs a way of accessing the public members of these objects.
This requirement can be addressed by implementing the following two design ideas.
Design Idea 1
Every visitor class that operates on objects of the same set of classes can be designed to implement a corresponding VisitorInterface interface.
A typical VisitorInterface declares a set of visit(ObjectType) methods, one for each object type from the object collection. Each of these methods is meant for processing instances of a specific class.
For example, if the object collection consists of objects of ClassA and ClassB, then the VisitorInterface interface would declare the following two methods:
for processing ClassA objects.
for processing ClassB objects.
Every object from the object collection makes a call to the r espective visit(ObjectType) method, passing itself as an ar gument.
A typical implementer (visitor) of the VisitorInterface can access the information required for the operation it is designed for by accessing the public members (methods and attributes) of the object instance passed to it through the visit method call.
Design Idea 2
Classes of objects from the object collection need to define a method:
A client interested in executing the visitor operation needs to:
Create an instance of the implementer (visitor) of the VisitorInterface interface that is designed to carry out the required operation.
Create the object collection and invoke the accept(visitor) method on every member of the object collection by passing the visitor instance created above.
As part of the accept(visitor) method implementation, every object in the object collection invokes the visit(ObjectType) method on the visitor instance.
Inside the visit(ObjectType) method, the visitor gathers the required data from the object collection to perform the operation it is designed for.