Skip to content

Visitor

Roberto Fronteddu edited this page Mar 7, 2023 · 2 revisions

The Visitor is a Behavioral Design Pattern.

  • The objective is to define new operations on an object without changing the class definition of the object.
  • The visitor object will visit all nodes in an object structure, each node has an accept method that has the visitor as a parameter.
  • Each time we want a new operation, we implement a new subclass of the visitor.
  • Objects know about the method defined in the visitor that they have to call to perform the operation.

Usefull when

  • We use this design pattern when we want to add new operations on an object without modifying the class of the object.

UML

visitor uml

  • Visitor: Defines methods that are specific to concrete classes.
  • ConcreteVisitorA/B: Provides a concrete implementation of the method specified in the interface.
  • Element: Defines the accept method that has as an argument the visitor.
  • ConcreteElementA/B: Implements accept calling the correct method for its class.

Implementation steps

  1. Create the visitor interface by defining the visit methods for each concrete class we want to support.
  2. The classes that want functionalities provided by this visitor must define the accept method which accepts a visitor. These methods are defined using the visitor interface as a parameter type so that we can pass any class implementing the visitor to these methods.
  3. In the accept method implementation, call a method on the visitor that is defined specifically for that class
  4. Implement the visitor interface in one or more classes. Each implementation provides specific functionality for interested classes. If we wanted another feature, we create a new implementation of the visitor.

Design considerations

  • Visitors can work with objects of classes that do not have a common parent. So having a common interface for those classes is optional. However, the code which passes our visitor to these objects must be aware of these individual classes.
  • Visitors need access to the internal state of the objects to carry out their work. So we may have to expose the state using getters/setters.
  • Related functionalities are grouped in a single visitor class instead of being spread across multiple classes. Adding a new functionality can be done by adding a new visitor class.
  • Visitors can accumulate state as they visit objects. We don't have to add a new state to objects for behavior defined in the Visitor.
  • Visitor can be used to add new functionalities to object structures implemented using composite or can be used for doing interpretation in Interpreter.

Comparison with Strategy

Visitor

  • All visitor subclasses provide possibly different functionalities from each other.

Strategy

  • In the strategy, each subclass represents a separate algorithm to solve the same problem.

Pitfalls

  • Visitor needs access to object's state -> weakens encapsulation
  • Supporting a new class in our visitor requires changes to all visitor implementations
  • If these classes change, then all visitors have to change as well since they have to work with the changed class.
  • Can be confusing to implement and understand

Real-Life Examples

  • dom4j library used for XML parsing. By implementing org.dom4j.Visitor and VisitorSupport we can process each node in an XML tree.
  • java.nio.file.FileVisitor and its implementation SimpleFileVisitor wee can process each file in a directory.
Clone this wiki locally