Version 1 of Visitor Pattern

Updated 2008-07-03 13:38:55 by nem

The Visitor Pattern is an OO Design Pattern that makes it easy to add new operations to a set of related classes without having to modify each class to add the new method. It is somewhat related to pattern matching and algebraic types. General discussions at [L1 ] and [L2 ].

Here is a simple example in Tcl to demonstrate the idea. The example here will be a simple OO tree representing integer arithmetic expressions (similar to expr, but much simpler). First, we define the nodes that represent each class, and give each a visit method:

package require XOTcl 1.5
namespace import xotcl::*
# A dummy Term class as superclass
Class Term
# Integers
Class Int -superclass Term
Int method init val { my set val $val }
Int method visit v { $v visitInt [my set val] }
# Addition
Class Add -superclass Term
Add method init {a b} { my set a $a; my set b $b }
Add method visit v {
    my instvar a b
    $v visitAdd [$a visit $v] [$b visit $v]
}
# Multiplication
Class Mul -superclass Term
Mul method init {a b} { my set a $a; my set b $b }
Mul method visit v {
    my instvar a b
    $v visitMul [$a visit $v] [$b visit $v]
}
# Create an example: t1 = (12 + (3 * 4))
Add t1 [Int new 12] [Mul new [Int new 3] [Int new 4]]

We can now use these visit methods to define as many operations as we want over our complex data-type:

# Pretty printer
Object pprint
pprint proc visitInt val   { return $val }
pprint proc visitAdd {a b} { return "($a + $b)" }
pprint proc visitMul {a b} { return "($a * $b)" }
# Simple interpreter/calculator
Object calc
calc proc visitInt val     { return $val }
calc proc visitAdd {a b}   { expr {$a + $b} }
calc proc visitMul {a b}   { expr {$a * $b} }
# Example:
puts "[t1 visit pprint] = [t1 visit calc]"
#=> (12 + (3 * 4)) = 24