Design patterns in C# – part 21 (Visitor pattern)

Role

The Visitor pattern defines and performs new operations on all the elements of an existing structure, without altering its classes.

Design

VisitorPattern

Implementation

  • Client -> TestVisitorPattern
  • Element -> Control
  • IVisitor -> Visitor
  • Visitor1 -> CountVisitor
using System;
using System.Collections.Generic;
using System.Reflection;

namespace VisitorPattern
{
    public class TestVisitorPattern
    {
        public static void Main(string[] args)
        {
            var root = new Control();

            var control1 = new Control();
            var control2 = new Control();
            var control3 = new Control();
            var control4 = new Control();
            var control5 = new Control();

            root.Controls.Add(control1);
            root.Controls.Add(control2);
            control2.Controls.Add(control3);
            control2.Controls.Add(control4);
            control2.Controls.Add(control5);

            Console.WriteLine("Count the elements");
            var visitor = new CountVisitor();
            visitor.CountElements(root);
            Console.WriteLine("Number of Elements is: {0}", visitor.Count);
        }
    }

    public abstract class Visitor
    {
        public void ReflectiveVisit(Control control)
        {
            var types = new[] {control.GetType()};
            MethodInfo methodInfo = GetType().GetMethod("Visit", types);

            if (methodInfo != null)
            {
                methodInfo.Invoke(this, new object[] {control});
            }
        }
    }

    public class CountVisitor : Visitor
    {
        public int Count { get; set; }

        public void CountElements(Control control)
        {
            ReflectiveVisit(control);

            if (control.Controls == null)
            {
                return;
            }

            foreach (Control c in control.Controls)
            {
                this.CountElements(c);
            }
        }

        public void Visit(Control control)
        {
            this.Count++;
        }
    }

    public class Control
    {
        public Control()
        {
            this.Controls = new List();
        }

        public List Controls { get; private set; }
    }
}

OUTPUT:

Count the elements
Number of Elements is: 6

Use when

  • You have a class hierarchy that is effectively sealed.
  • There are many distinct operations to perform on it.
  • The operations are orthogonal to the core purpose of the types in the hierarchy.
  • You need the flexibility to define new operations over time.

Bibliography

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s