Visitor

From CSSEMediaWiki
Revision as of 04:24, 19 October 2010 by Jenny Harlow (Talk | contribs)
Jump to: navigation, search

Contents

Introduction

The Visitor is a behavioral design pattern. It allows the designer to define new operations on an object structure and its elements, without modifying the object structure itself.

Use When

You should use the Visitor pattern when:

  • An object structure contains many classes with different interfaces that you want to perform operations on depending on the concrete class of the objects.
  • Many unrelated operations need to be performed on the parts of an object structure and you don't want to pollute the classes' interface by adding these operations. Visitor allows you to gather these operations in a separate class instead.
  • The classes defining the object structure rarely change but you expect to frequently add new operations to be performed on them.

Structure

The Visitor describes the relations between three distinct classes:

  • ObjectStructure - Provides a visitor with access to its elements
  • Element - Accepts visits.
  • Visitor - Accesses an element to perform operations.


Figure 1 graphically describes these Visitor pattern relationships.

The Visitor pattern uses Double dispatch to reduce the coupling between the visitor and the object structure.


Figure 1: A UML 2.1 class diagram describing the Visitor structure

Communication

The Visitor pattern allows a visitor object to access and perform operations on an element object. A summary of the Visitor pattern communications is given in Fig. 2. Here the following interactions are shown:

  • Sequence 1 - The object aVisitor1 performs an operation on anElementA
  • Sequence 2 - The object aVisitor2 performs an operation on anElementA
  • Sequence 3 - The object aVisitor1 performs an operation on anElementB
  • Sequence 4 - The object aVisitor2 performs an operation on anElementB


Figure 2: A UML 2.1 communication diagram describing the interactions between objects in the Visitor pattern

Consequences

Benefits

  1. Adding new operations is easy. Just add a new Visitor class
  2. Separates unrelated behaviours and gathers related ones
  3. Visit across more than one class hierarchy

Liabilities

  1. Adding a new ConcreteElement is difficult
  2. Elements may expose otherwise private attributes

Conflicts

The Acyclic Dependencies Principle

The Visitor pattern conflicts with the Acyclic dependencies principle. Here, the concrete visitor depends on the interface of the concrete elements it visits. Similarly, the concrete elements must be familiar with interface of all visiting concrete visitors.

Mitigation

  • Where a visitor pattern is necessary, the ill effects of cyclic dependency can be mitigated by ensuring that cyclically dependent classes are deployed within the same package.
  • Bob Martin suggests a solution to this problem in his paper Acyclic Visitor. This solution uses casting to move the dependency from the interface of the concrete elements to the implementation. The abstract element is designed to depend on the abstract visitor, within a concrete element's implementation, down-casting is used to extract and consume the concrete visitor's interface.

Keep related data and behaviour in one place

The Visitor pattern deliberately violates Riel's heuristic Keep related data and behavior in one place by separating the desired behaviour from the data on which it operates. This means that getters and setters will need to be added to the object structure to allow the visitor to get at the data it needs. This is usually a sign that related data and behaviour is not kept in one place. Adding getters and setters to the object structure also violates related heuristics such as the Law of Demeter and Tell, don't ask. In addition, it compromises the encapsulation of data in the object structure, allowing access to this data not just from the visitor but from other parts of the system.

Coupling

The Visitor design pattern can lead to tight coupling between the visitor and the object structure. This happens because the behaviour has been separated from the data.

Related Patterns

  • Composite: Visitors can be useful to perform operations over a composite object structure.
  • Interpreter: Visitors can be used to do the interpretation.

Conflicting Heuristics

See also


Personal tools