Java Reference
In-Depth Information
To implement the Visitor pattern, use the following:
Visitor -
The abstract class or interface that defines a
visit
method for each of the
ConcreteElement
classes.
ConcreteVisitor -
Each concrete visitor class represents a specific operation to be performed for the system. It
implements all the methods defined in
Visitor
for a specific operation or algorithm.
Element -
An abstract class or interface that represents the objects upon which the
Visitor
operates. At a
minimum, it defines an
accept
method that receives a
Visitor
as an argument.
ConcreteElement -
A concrete element is a specific entity in the system. It implements the
accept
method
defined in
Element
, calling the appropriate
visit
method defined in
Visitor
.
One issue to watch for when implementing the Visitor pattern involves overloaded methods. The pattern uses
overloaded methods for the
visit
method.
Figure 2.15
s
hows that the
Visitor
interface has two
visit
methods,
each taking a different argument. These are two completely different methods from the language point of view.
Although the implementation of the accept method in each
ConcreteElement
class is very similar (even completely the
same), you cannot put that operation in a superclass. Doing so results in the
visit
method being called with the
supertype as argument, even though the actual type of the instance may be a specific
ConcreteElement
.
Benefits and Drawbacks
Because of its structure, the Visitor pattern makes adding behavior to a system very easy. When you initially
implement the pattern, you develop a support framework for any other
Visitor
action you might want to perform
in the future. To add new functionality, simply create a new class that implements the
Visitor
interface and
write new functional code.
Visitors are useful because they allow you to centralize functional code for an operation. Apart from making the
code easier to extend or modify in the long term, this approach makes maintaining state straightforward. The
same
Visitor
object is normally used to visit every
Element
in a structure, so it provides a central location to
hold data being collected, or to store intermediate results.
The downside of the pattern is that there is very little flexibility in the
Element
class chain. Any addition or
modification to the
Element
class hierarchy has a good chance of triggering a rewrite of the
Visitor
code
structure. Any additional class requires a new method to be defined in the
Visitor
interface and each
ConcreteVisitor
has to provide an implementation for that method.
In addition, the pattern breaks, or at least severely bends, the object-oriented principle of code encapsulation. The
Visitor pattern takes code that applies to an object out of the object's class and moving it to another location.