You can see this and other great articles on Design Patterns here.
The Visitor Design Pattern allows you to decouple the logics and the data structures and while applying the logics to the data structures. With this pattern, you can build classes that focus only on the data structures without knowing the logics that will be applied to the structure. At the same time, you can build classes that concentrate solely on the logics that will be applied to the structure without knowing what the structure looks like. The benefit is that the evolution of the logics and the structures can vary independently.
Let’s look at the UML of the Visitor pattern first, then we will look at an example to see how it works. Below is the UML of the Visitor Design Pattern:

- The left hand side are the classes for the structures
- The
IElement interface defines the elements in the structure.
- It has the
Accept method that takes in an IVisitor.
- The
ConcreteElement class implements the IElement interface. You will have multiple types of ConcreteElement classes where each represents a different structure.
- It has the
Accept method that takes in an IVisitor that will apply the logic to the element.
- The right hand side are the classes for the logics
- The
IVisitor interface defines the logics supported.
- It has the
Visit method that takes in an IElement.
- The
ConcreteVisitor class implements the IVisitor interface. You will have multiple types of ConcreteVisitor classes where each represents different logic.
- It has the
Visit method that takes in an IElement that will apply the logic to the element.
Let's see an example. We will define two types of visitors: SantaClaus and MailCarrier. They both contain logics that will be applied to the structure.
We will define two types of structures, Household and BusinessEntity. They are the data structures where the visitors can apply their logics to. Both the Household and BusinessEntity can be visited by SantaClaus or MailCarrier.
The UML of our example is shown below:

- The left hand side are the classes for the structures
- The
IElement interface defines the elements in the structure.
- It has the
Accept method that takes in an IVisitor.
- The
HouseHold and BusinessEntity classes implement the IElement interface.
- They have the
Accept method that takes in an IVisitor that will apply the logic to the element.
- The right hand side are the classes for the logics
- The
IVisitor interface defines the logics supported.
- It has the
Visit method that takes in an IElement.
- The
SantaClaus and MailCarrier classes implement the IVisitor interface.
- They have the
Visit method that takes in an IElement that will apply the logic to the element.
You can extend the Visitor pattern by applying the Composite pattern to the structure part of the Visitor pattern, essentially forming a tree using the IElement as the interface for the tree structure where all the visitors can apply their logic to the tree structure. But for the purpose of demonstrating the Visitor pattern only, we will not make this extension in our implementation code.
Below are the implementation code and the output of our example. Notice that you can develop the structure and the logic parts independently, and yet you can easily apply the logics to the structures in the client code:
class Program
{
static void Main(string[] args)
{
List<ielement> list = new List<ielement>();
list.Add(new Household("The Adams Family"));
list.Add(new Household("The Jones Family"));
list.Add(new BusinessEntity("The Oatmeal Bakery"));
list.Add(new BusinessEntity("The Ice Cream Shop"));
IVisitor visitor = new SantaClaus();
foreach (IElement i in list)
i.Accept(visitor);
visitor = new MailCarrier();
foreach (IElement i in list)
i.Accept(visitor); }
}
public interface IElement
{
string Name { get; set; }
void Accept(IVisitor v);
}
public class Household : IElement
{
private string name;
string IElement.Name
{
get { return name; }
set { name = value; }
}
public Household(string name)
{
this.name = name;
}
void IElement.Accept(IVisitor v)
{
v.Visit(this);
}
}
public class BusinessEntity : IElement
{
private string name;
string IElement.Name
{
get { return name; }
set { name = value; }
}
public BusinessEntity(string name)
{
this.name = name;
}
void IElement.Accept(IVisitor v)
{
v.Visit(this);
}
}
public interface IVisitor
{
void Visit(IElement e);
}
public class SantaClaus : IVisitor
{
void IVisitor.Visit(IElement v)
{
Console.WriteLine("Santa visited " + v.Name);
}
}
public class MailCarrier : IVisitor
{
void IVisitor.Visit(IElement v)
{
Console.WriteLine("MailCarrier visited " + v.Name);
}
}

Liked this article? You can see this and other great articles on Design Patterns here.