Visitor Design Pattern
The Visitor Pattern:
This pattern comes under behavior pattern category because it manages the algorithm to be used when the visitor varies.
According to the Gang of four book on design patterns, visitor lets you define a new operation without changing the classes of the elements on which it operates. It actually decouples expression tree structure from operations performed on it.
Let's check, at first , the class diagram of an example without using the Visitor pattern.
The Shape structure hierarchy is organized as a composite structure and can be implemented by a Composite design pattern.
Figure1: Class diagram using Visitor Pattern
Why should we not implement this example without visitor?
We want to add a new operation over the the object Shape. The only solution which limits extensibility is hard coding the method drawSahpe() in Shape interface and in the sub-classes.
It would be better if each new operation could be added separately, and if the shape interface and sub-classes were independent of the operations that apply to them.
Let's see now how to add an operation in the case we have the Shape example implemented using Visitor pattern.
1. Decouple operations on Shape from its structure. We create a based Visitor interface that define visit() operations on each type of Shape object (sub-classes). Then we will Subclass this interface in order to define the different type of visitors PrintVisitor, DrawVisitor and AnalysisVisitor and so on. This makes adding an operation easy and provides flexibility.
Figure2: Class diagram of the ShapeVisitor hierarchy
2. Define an accept() method in the Shape interface to which an instance of sub-classes of ShapeVisitor is passed. The implemented accept() method in the sub-classes of Shape has a callback to the visitor.visit() method passing in the object itself as a parameter.
Following is the complete class diagram of the example using the Visitor Pattern.
Figure3: Class diagram using Visitor Pattern
When use Visitor design pattern?
- When classes define unrelated operations
- Class relationships rarely changes but operations on them do change.
Tight coupling Circular dependency between Visitor and element interfaces. If we add a new subclass of Shape interface, this will affect the vistorShape API.
Ralph Johnson; Richard Helm; Erich Gamma; John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software.Addison-Wesley Professional, 1994
Design Patterns in Java Tutorial. https://www.tutorialspoint.com/design_pattern/visitor_pattern.htm