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



References
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

Reading

Design Patterns text, pp. 331-334

Doc 7, Visitor Pattern Slide # 2

Visitor

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 -
AVL
Red-Black



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}
   etc.
}


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 {
   blah
}
   
class AVLTree extends BinaryTree {
   blah
}
   
class RedBlackTree extends BinaryTree {
   blah
}
class PreorderTree extends BinayrTree {
   blah
}
   
etc.

Doc 7, Visitor Pattern Slide # 5
Solution 3





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

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

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


Doc 7, Visitor Pattern Slide # 6

Structure




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

Consequences



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

Variations

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
ExtrinsicVisitor


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