# Design Pattern Variations: A Better Visitor

• Print
Radu Braniste critiques the Visitor Pattern (VP), reiterating its disadvantages and questioning its value as a pattern in a very exhaustive manner. As usual, this kind of thorough analysis proves to be a fertile ground for new ideas: This article presents a couple of variations of the pattern responding systematically to all the major shortcomings of VP.

The starting point of this article was an extremely interesting critique [1] of the Visitor Pattern (VP), reiterating its disadvantages and questioning its value as a pattern in a very exhaustive manner. As usual, this kind of thorough analysis proves to be a fertile ground for new ideas—this article will present a couple of variations of the pattern responding systematically to all the major shortcomings of VP.

## A Problem Visitor

The following is a short description of the original Visitor Pattern (VP), emphasizing its mechanics and the way in which it affects its perceived usability. We will use the example provided in the aforementioned article to illustrate.

VP is often defined as "a way of separating an algorithm from an object structure upon which it operates." This description implies the existence of three main collaborating parts:

• An algorithm (ALG)
• A structure of objects (SO)
• A way of traversing 2 to apply 1 (TRAV)[1]

The alert reader will observe immediately a similitude with STL and the way it separates data from algorithms. The obvious benefit is that we can freely vary the algorithms working on top of the same data. The difference is that SO is a structure of unrelated objects[2] that can be independently inspected during traversal, whereas in STL we deal with collections of homogeneous components.

Let's consider the following standard example ([1]):

```class Hammer;
class Drill;

class Visitor
{
public:
void visit(Hammer & h) = 0;
void visit(Drill & d) = 0;
};

// root of the given hierarchy
class Tool
{
public:
virtual void accept(Visitor & v) = 0;

// regular operations of Tool omitted
};

class Hammer : public Tool
{
public:
virtual void accept(Visitor & v) { v.visit(*this); }

// regular operations of Hammer omitted
};

class Drill : public Tool
{
public:
virtual void accept(Visitor & v) { v.visit(*this); }

// regular operations of Drill omitted
};

class DoSomethingVisitor : public Visitor
{
public:
void visit(Hammer & h)
{
// do something with the hammer
}

void visit(Drill & d)
{
// do something with the drill
}

};

vector<Tool *> myToolBox; // filled with lots of tools

void doSomethingWithAllTools()
{
DoSomethingVisitor v;

for (size_t i = 0; i != myToolBox.size(); ++i)
{
Tool & t = *(myToolBox[i]);
t.accept(v);
}
}```

Observations:

• Visitor is the family of algorithms ALG that can be applied to an unrelated structure of objects SO(Hammer, Saw)
• In order to traverse SO, VP requires all elements of SO to implement an artificial interface—an acceptor (Tool, in this case). This allows SO to behave polymorphically and be iterated (vector<Tool *> myToolBox). This interface is not necessary otherwise, and its implementation is mechanical.