Decoupling Data Structures from Algorithms

The Visitor Pattern


I. Functional List Structure

Recall the functional list data structure, FunList.

funlist.png (5945 bytes)

Each time we want to compute something new, we have to edit each class and add appropriate methods to each class.  Is there a way to add new behavior to FunList (and its variants) without touching any of the existing code, leaving everything that has been written so far unchanged?


II. Functional List Framework

The key is to encapsulate the variant behaviors into a separate union pattern (OOPP #1).  Here, the variant behaviors are the ininitely many algorithms (i.e. computations) that we want FunList to .  The invariant behaviors are the methods car () and cdr ().  For FunList to execute any of these algorithms, we just need to add to the design of FunList one more method and never have to modify anything ever again!

funFW.png (16275 bytes)

This is an example of what is called the Visitor Pattern.  Class FunListFW is calle the host and its method execute () is called a "hook" to the IFunAlgo visitors.  Via polymorphism, FunListFW knows exactly what method to call on the specific IFunAlgo visitor.  As such, FunListFW is said to be a framework for reusing and extending the list structure.  It is capbale of executing any algorithm, past, present, and future, that conforms to the IFunAlgo interface.  IFunAlgo is said to define a protocol for communication between a list and algorithms on a list.

III. The Visitor Pattern

The visitor pattern is a framework for communication and collaboration between two union patterns: a "host" union and a "visitor" union.  An abstract visitor is usually defined as an interface in Java.  It has a separate method for each of the concrete variant of the host union.  The abstract host has a method (called the "hook") to "accept" a visitor and leaves it up to each of its concrete variants to call the appropriate visitor method.  This "decoupling" of the host's structural behaviors from the extrinsic algorithms on the host permits the addition of infinitely many external algorithms without changing any of the host union code.  This extensibility only works if the taxonomy of the host union is stable and does not change.  If we have to modify the host union, then we will have to modify ALL visitors as well!

visitor.png (12556 bytes)

In practice, the host union is encapsulated inside of another class, say Structure.   A client program, say StructClient, only deals with the Structure class and the IVisitor interface.  An appropriate "factory" will provide the client with concrete visitors that it wants.  All the "state-less" visitors should be singletons and are factories that manufacture unique instances of themselves!  We will learn more about factories in the near future.  Programs designed in this manner exemplify what is coined in software engineering the principle of information hiding.

 

dxnguyen@cs.rice.edu
Copyright 1999, Dung X. Nguyen - All rights reserved.