The Visitor Pattern

Presented by Julie Watson (juliew@) and Stephen Huey(sirstevo@) on 2/27/02

The main purpose of the Visitor pattern is that it allows you to define new operations for a set of classes without changing the actual classes on which it will operate.

To implement a visitor, you must first have an element hierarchy. The main element class must define an abstract method, Accept, which takes in a Visitor. All concrete implementations of this class must implement the Accept operation. In the method, it calls the appropriate argument in the visitor that will perform the operation needed for its class. It also passes itself to the Visitor so that it can be operated on. With this structure, a Visitor can easily be added to the program. There must be an abstract Visitor class, which defines an operation for each of the classes being operated on. Any concrete implementation of the Visitor must write each of these methods so that any of the Elements can be correctly evaluated.

Uses:

You have a series of classes on which you will want to perform some operation, which depends on the operand’s class. There are many operations to perform on a set of objects. Using visitors for each will keep the class definitions simple and uncluttered.

When not to use:

If the class structure changes with much frequency, the Visitor will be very inefficient. Each new class added or removed would require a change to the Abstract Visitor class, and each of the concrete implementations of the visitor. This can be a very costly change.

Benefits:

Makes adding new operations easy. Without the Visitor, anytime you want to add a new operation that will operate over a set of objects, each of their class definitions must be changed. With the Visitor interface already implemented, all that must be done for the new function is to write a new visitor. Groups together related operations. Therefore functions that perform the same operation over many objects are gathered together in one class. If you decide to change something about that particular interaction, you can simply update the one visitor. A visitor can visit across any class hierarchy. It is not required that the classes over which it visits have the same parent class or interface. Visitors can accumulate state as they traverse the elements.

Possible downfalls:

Could be more trouble than it’s worth if the Concrete Element hierarchy changes more than the functions that you want to apply to the elements. Frequent changes to the class structure require updates to all visitors and can be an easy source of error. In order for a visitor to do its work, the element class must provide a public method for the visitor to use. This allows access to private members of a class by external sources and could compromise the object.