SDSU CS 635 Advanced Object-Oriented Design & Programming
Spring Semester, 2001
Visitor Pattern
Previous    Lecture Notes Index    Next    
© 2001, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 25-Feb-01

Contents of Doc 7, Visitor Pattern

Design Patterns: Elements of Resuable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1995, pp. 331-344

"Default and Extrinsic Visitor", Martin E. Nordberg III, in Pattern Languages of Program Design 3, Edited by Martin,
Riehle, Buschmmann, Addison-Wesley, 1998, pp. 105-123

"Acyclic Visitor", Robert C. Martin, in Pattern Languages of Program Design 3, Edited by Martin,
Riehle, Buschmmann, Addison-Wesley, 1998, pp. 94-104


Design Patterns text, pp. 331-334

Doc 7, Visitor Pattern Slide # 2


Example - Trees

What about preorder visit, postorder visit?
What about an HTML print?
What about printing a 2D representation?
What if this was an expression tree - evaluation?
What if this was a binary search tree - adding, deleting
What about balancing the binary search tree -

Doc 7, Visitor Pattern Slide # 3
Solution 1

Build all the operations into the tree structure

This works in many situations

If you need to add a lot of operations the classes can become cluttered

class BinaryTree {
   public String htmlPrint() { blah}
   public String 2DPrint() { blah}
   public String preorderTraversal() { blah}
   public String postorderTraversal() { blah}
   public String avlAdd() { blah}
   public String RedBlackAdd() { blah}

Doc 7, Visitor Pattern Slide # 4
Solution 2

Use different classes or subclasses for the different types of trees

Does not work in classes we want to be able to mix all combinations

class BinaryTree {
class AVLTree extends BinaryTree {
class RedBlackTree extends BinaryTree {
class PreorderTree extends BinayrTree {

Doc 7, Visitor Pattern Slide # 5
Solution 3

class BinaryTreeNode {
   public void accept(Visitor aVisitor) {
      aVisitor.visitBinaryTreeNode( this );

class BinaryTreeLeaf {
   public void accept(Visitor aVisitor) {
      aVisitor.visitBinaryTreeLeaf( this );

abstract class Visitor {
   abstract void visitBinaryTreeNode( BinaryTreeNode );
   abstract void visitBinaryTreeLeaf( BinaryTreeLeaf );
class HTMLPrintVisitor extends Visitor {
   public void visitBinaryTreeNode( BinaryTreeNode ) {
      HTML print code here

Doc 7, Visitor Pattern Slide # 6


This is more complex than solutions 1 & 2

The structure, an iterator, or the visitor can do the traversal

The visitor is told what type it is acting on, so using the wrong visitor will be a compile error

Doc 7, Visitor Pattern Slide # 7

When to Use Visitor

Doc 7, Visitor Pattern Slide # 8


If the structure involves many different classes then adding a new operation to the structure requires changing all those classes

To add a new ConcreteElement you need to change all existing visitors

Text claims iterators can not iterate through structure containing unrelated classes

However, the visitor assumes that each element in the structure contains a visit method, which implies at least a common visit interface for all elements

Visitor can accumulate information

The visitor may force you to provide public operations in the elements that you would not otherwise make public

C++ friends are useful here

Doc 7, Visitor Pattern Slide # 9


Function Overloading

Overloading allows the accept method to be implemented once in the Element class

Eliminates cyclic compile dependencies

Doc 7, Visitor Pattern Slide # 10

The Visitor takes the responsibility of making sure a visitor can visit a particular concrete element

Each Visitor knows which types of concrete classes it can visit

The canVisit method of each visitor returns true if that visitor can visit that concrete type

New visitors can be created without changing the Element classes

New Element classes can be added without having to change old visitors

Doc 7, Visitor Pattern Slide # 11
The above is slightly modified from the original ExtrinsicVisitor pattern

In the original

Element does not have an accept method
The visit method of ExtrinsicVisitor does not call canVisit
ObjectStructure calls canVisit to determine if an element can be visited, then calls visit
The visitElement methods are not over loaded

Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 25-Feb-01    Next