The Visitor pattern uses an external class to act on data in other classes. This is a useful approach to you when you have a polymorphic operation that cannot reside in the class hierarchy. Visitor is also a useful way to extend the behavior of a class hierarchy without the need to alter existing classes or to implement the new behavior in every subclass that requires it.

image

I think the visitor pattern feels a bit of a weird pattern. I mean weird in a way that it feels not very object-oriented nor structured way of programming. On the other hand, sometimes you have a collection of similar classes which differ in one or more methods. If you don’t want to ‘pollute’ your object-oriented hierarchy with these class-specific methods, then you can use the visitor pattern.

All the client needs is an object structure, a visitor and an element. One or more elements are attached to the object structure. The visitor visits the object structure and does ‘something’ with the attached elements.

class Client
{
    static void Main()
    {
        ObjectStructure objectstructure = new ObjectStructure();
        Element element = new ConcreteElement();
        objectstructure.Attach(element);
        ConcreteVisitor visitor = new ConcreteVisitor();
        objectstructure.Accept(visitor);
        Console.ReadKey();

    }
}

The abstract class Visitor can have one or more concrete implementations, which do their work on the attached elements.

abstract class Visitor
{
    public abstract void VisitConcreteElement(ConcreteElement concreteElement);
}

class ConcreteVisitor : Visitor
{
    public override void VisitConcreteElement(ConcreteElement concreteElement)
    {
         Console.WriteLine("{0} visited by {1}", concreteElement.GetType().Name,          this.GetType().Name);
    }
}

The element class accepts a visitor and propagates an operation towards this visitor.

abstract class Element
{
    public abstract void Accept(Visitor visitor);
}

class ConcreteElement : Element
{
    public override void Accept(Visitor visitor)
    {
        visitor.VisitConcreteElement(this);
    }

    public void Operation()
    {
    }
}

The object structure contains all machinery needed for maintenance of a list of attached elements. In this way it resembles the subject class of the observer pattern.

class ObjectStructure
{
    private List m_Elements = new List();
    public void Attach(Element element)
    {
        m_Elements.Add(element);
    }
    public void Detach(Element element)
    {
        m_Elements.Remove(element);
    }
    public void Accept(Visitor visitor)
    {
        foreach (Element element in m_Elements)
        {
            element.Accept(visitor);
        }
    }
}

By now you should get some idea how the visitor pattern works.

Handy? I am not sure, I never used it in real life. What do you think. Please let me know.

This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.