Tuesday, October 13, 2015

Design Pattern - Visitor pattern

Definition:
From gang of four -  "Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates".

Head First - "Use the Visitor pattern when you want to add capabilities to a composite of objects and encapsulation is not important".

In short - "Defines a new operation to a class without change"

How to use Visitor pattern:
1. Two types of objects needed, one is called 'element', other is called 'visitor'

2. Create a base visitor class hierarchy with "visit" method for each concrete derived class the composite hierarchy. Each "visit" method accepts a single argument - reference to the original element derived class

3. Each derived concrete class of visitor base class has to provide implementation of each "visit" method

4. Add abstract/virtual "accept" method in base element hierarchy. This takes an argument of abstract base class of visitor hierarchy 

5. All sub-element or derived concrete classes has to provide implementation of "accept" method by simply calling "visit" method of passed concrete Visitor class where "this" is passed as reference

6. For any operation needed for client will create and instance of concrete visitor class and pass that as reference to "accept" method in each concrete element class. The client of Visitor pattern is called traverser which knows how to guide the visitor through the composite structure. 

Class diagram:


















Examples:
1. A restaurant Application might have menu, menu item and ingredient objects with related attributes and operations. If reality changes where customers demand nutritional information on menu items as well as on ingredients, rather making elements (menu, menu item, ingredient etc) level changes visitor pattern can be implemented.

2. A Shopping cart where we can add different type of items (Elements), when we click on checkout button, it calculates the total amount to be paid. Now we can have the calculation logic in item classes or we can move out this logic to another class using visitor pattern

Benefit:
1. Allows to add operations/functionalities to a composite structure without changing the structure itself
2. Adding new operations/functionalities is relatively easy
3. The code for operations performed by the Visitor is centralized

Trade-off:
1. The composite classes' encapsulation is broken when the visitor pattern is used
2. Because the traversal function is involved, changes to composite structure are more difficult


Notes:
1. Double dispatch - the operation executed depends on: the name of the request (method name), and the type of TWO receivers (the type of the Visitor and the type of the element it visits)

From above class diagram double dispatch can be as below - 
  • When the accept method is called in the program, its implementation is chosen based on both: 
    • The dynamic type of the element. 
    • The static type of the visitor. 
  • When the associated visit method is called, its implementation is chosen based on both: 
    • The dynamic type of the visitor. 
    • The static type of the element as known from within the implementation of the accept method, which is the same as the dynamic type of the element. (As a bonus, if the visitor can't handle an argument of the given element's type, then the compiler will catch the error.) 
  • Consequently, the implementation of the visit method is chosen based on both: 
    • The dynamic type of the element. 
    • The dynamic type of the visitor.

2. A more flexible approach to this pattern is to create a wrapper class implementing the interface defining the accept method. The wrapper contains a reference pointing to the 'abstract base element' which could be initialized through the constructor. This approach avoids having to implement an interface on each element. (Resource-04)


Resources:
1. Head First Design Pattern
2. https://sourcemaking.com/design_patterns
3. https://en.wikipedia.org/wiki/Visitor_pattern
4. Java Tip 98: Reflect on the Visitor design pattern

No comments: