Java Reference
In-Depth Information
Visitor
Pattern Properties
Type: Behavioral, Object
Level: Component to System
Purpose
To provide a maintainable, easy way to perform actions for a family of classes. Visitor centralizes the behaviors
and allows them to be modified or extended without changing the classes they operate on.
Introduction
Imagine you want the Personal Information Manager to have project planning capability, and the project planner
is used for things like bidding, risk analysis, and time estimation. The following classes represent a complex
project:
Project - The root of the project hierarchy, representing the project itself
Task - A work step in the project
DependentTask - A work step that depends on other tasks for its own completion
Deliverable: An item or document to be produced as a result of the project
To clearly identify these classes as part of a common model, they're organized around an interface called
ProjectItem .
So far so good. Now, how do you code the ability to estimate the total cost for the project? The calculation will
probably depend on the specific type of ProjectItem . In that interface you define a method getCost that should
calculate the costs for that specific part of the project. This would allow you to compute the cost for every item in
the project structure.
You might decide on an approach like this:
Project - No operation, since the cost is equal to the cost of all other project items.
Simple task - Cost is based on estimated hours of effort.
Dependent task - Same as simple task, but adds an additional factor to represent coordination based on the task
dependencies.
Deliverable - Cost is a basic estimate of materials plus production cost.
However, how should you calculate the time required for the project, and project risk? Using the same approach
as for the cost makes the code harder to maintain. With every new capability, you have to write a bunch of new
methods that are spread throughout the project classes. With every new operation, the classes become larger,
more complex, and harder to understand.
It is also difficult to keep track of information with this kind of approach. If you try to estimate cost, time, or risk
using localized methods, you have to figure out how to maintain the intermediate results, since each method
belongs to a specific project object. You will likely wind up passing the information through the entire project
tree, then crossing your fingers and hoping that you'll never have to debug it.
The Visitor pattern offers an alternative. You define a single class, with a name like CostProjectVisitor , that
performs all cost-related calculations. Instead of computing cost in the ProjectItems themselves, you pass them
to the Visitor class, which keeps a running tally of the total cost.
ProjectItems no longer has a getCost method. Instead, it has a more generic acceptVisitor method that uses
a ProjectVisitor to call a specific method on the ProjectVisitor . For instance, the acceptVisitor method
 
Search WWH ::




Custom Search