Corey Coogan

Python, .Net, C#, ASP.NET MVC, Architecture and Design

  • Subscribe

  • Archives

  • Blog Stats

    • 110,810 hits
  • Meta

Visitor Pattern: A Real World Example

Posted by coreycoogan on June 16, 2009

Vistor

Vistor

The Visitor pattern is a powerful design pattern that I see a lot less then its popular brethren such as Factory, Facade, Command and Singleton. I believe this is because the pattern is often a bit more difficult for developers to understand and much of the articles and examples out there lack a real world example.

The Gang of Four defines the Visitor as:

Represent an operation to be performed on elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

The very nature of the Visitor makes it an ideal pattern to plug into public API’s, thus allowing its clients to perform operations on a class using a “visiting” class without having to modify the source. Once familiar with this pattern, you will see the opportunity to apply it whenever you are dealing with composites or collections of interfaces/base classes.

A Real World Example

I have been working on a project that uses a third-party application database. The database is very large and provides a set of base tables that are completely generic. These tables look much like what you find in SharePoint, with column names like CHAR_01, CHAR_02, DATE_01, DATE_02. The application adds meaning to these generic tables by creating Views with meaningful column names in the database to sit on top of them. For example, the EntryView will essentially map a field called BeginDate to the base table’s DATE_01 field.

A code generator has been written to interact with this database from .Net applications. The generator creates of class for each base table as well as a class for each view, which decorates the base table.

Here’s what that table/view structure looks coming out of the generator:

    public class BaseTableRecord
    {
        public int Int01 { get; set; }
        public string Char01 { get; set; }
        public bool Char02 { get; set; }
        public bool Bool01 { get; set; }
    }

    public abstract class PartyBaseView
    {
        public PartyBaseView (BaseTableRecord record)
        {
            BaseRecord = record;
        }

        public BaseTableRecord BaseRecord { get; private set; }
    }

    public class PartyEntryView : PartyBaseView
    {
        public PartyEntryView (BaseTableRecord record)
            : base(record)
        { }

        public int NumberInParty
        {
            get { return BaseRecord.Int01; }
            set { BaseRecord.Int01 = value; }
        }

        public string PartyName
        {
            get { return BaseRecord.Char01; }
            set { BaseRecord.Char01 = value; }
        }
    }

    public class PartyExitView : PartyBaseView
    {
        public PartyExitView (BaseTableRecord record)
            : base(record)
        { }

        public int ExitingParty
        {
            get { return BaseRecord.Int01; }
            set { BaseRecord.Int01 = value; }
        }

        public string Payor
        {
            get { return BaseRecord.Char01; }
            set { BaseRecord.Char01 = value; }
        }
    }

To remain generic, the primary type that is deal with is a collection of PartyViewBase types. Now there are all sorts of actions we will want to perform on these different views. Because any single Use Case could deal with a collection of PartyViewBase types, consisting of one or more instances of multiples PartyViewBase implementations, we need a way to interact with each inside an iteration without casting. A perfect example Use Case would be the need to map each view to an XML file. Let’s see how Visitor pattern (which will ultimately have to be added to the code generator) will work for me.

First I’m going to define the IPartyViewVisitor interface for my Visitor:

    public interface IPartyViewVisitor
    {
        void Visit(PartyEntryView view);
        void Visit(PartyExitView view);
    }

Now I’m going to add a method to my PartyBaseView to allow the methods on my visitor to be invoked. Here’s what that abstract method looks like:

public abstract void Accept(IPartyViewVisitor vistor);

Here’s what the classes look like now that they’ve fully implemented the pattern:

    public abstract class PartyViewBase
    {
        public PartyViewBase(BaseTableRecord record)
        {
            BaseRecord = record;
        }

        public BaseTableRecord BaseRecord { get; private set; }

        public abstract void Accept(IPartyViewVisitor vistor);
    }

    public class PartyEntryView : PartyViewBase
    {
        public PartyEntryView(BaseTableRecord record)
            : base(record)
        { }

        public override void Accept(IPartyViewVisitor vistor)
        {
            vistor.Visit(this);
        }

        public int NumberInParty
        {
            get { return BaseRecord.Int01; }
            set { BaseRecord.Int01 = value; }
        }

        public string PartyName
        {
            get { return BaseRecord.Char01; }
            set { BaseRecord.Char01 = value; }
        }

    }

    public class PartyExitView : PartyViewBase
    {
        public PartyExitView(BaseTableRecord record)
            : base(record)
        { }

        public override void Accept(IPartyViewVisitor vistor)
        {
            vistor.Visit(this);
        }

        public int ExitingParty
        {
            get { return BaseRecord.Int01; }
            set { BaseRecord.Int01 = value; }
        }

        public string Payor
        {
            get { return BaseRecord.Char01; }
            set { BaseRecord.Char01 = value; }
        }
    }

Next, I need to write an IPartyViewVisitor implementation to handle mapping my Views to XML files.

    public class PartyViewMapperVisitor : IPartyViewVisitor
    {
        //would take some infrastructure class in the constructor

        #region IPartyViewVisitor Members

        public void Visit(PartyEntryView view)
        {
            //do mapping here
            Console.WriteLine("Mapping PartyEntryView");
        }

        public void Visit(PartyExitView view)
        {
            //do maping here
            Console.WriteLine("Mapping PartyExitView");
        }

        #endregion
    }

Now I’ll put it all together and get a list of PartyViewBase instances, loop through them, and let my Visitor implementation do the work.

    //instantiate my repository, service or whatever
    PartyRepository repo = new PartyRepository();

    //get my list of PartyViewBase instances
    IList parties = repo.GetAllParties();

    //instantiate my mapping visitor
    PartyViewMapperVisitor visitor = new PartyViewMapperVisitor();

    //loop through my PartyViewBase instances
    foreach (var viewBase in parties)
    {
         //perform my mapping
         viewBase.Accept(visitor);
    }

Conclusion

The Visitor pattern allows you to define an operation on a class without changing that class. Because a Visitor is defined as an interface, visitor implementations can be written for multiple needs and the target class never gets touched, adhering to OCP. Whenever you are dealing with composites, think about using the Visitor pattern to make your life easier. It’s also great to stub the Visitor into public API’s to grant your clients, and yourself, future access without modification.

Advertisements

5 Responses to “Visitor Pattern: A Real World Example”

  1. Corey,
    Nice example! I could see this being a monthly series…”Design Pattern Examples In The Real World!”…I would read it.

    FYI. You should get your blog more “discoverable”. Go out to Google and get it signed up so there bot can find and process it.

    DotNetDevDude

  2. Fathom Savvy said

    Thanks for the Article! It was enough to make me realize rhat the pattern is designed to be used with Polymorphic classes. You setup the interface so that it has a Visit method for each of the derived classes. Then you can create any class (implementing the interface) to do whatever you want with each of the derived classes. So I’m thinking you’d only want to use the visitor pattern if you have a need for one class to use all of the derived classes. If the class in question only used 1 of the derived classes, then a different pattern would be called for. Right? Or would you use the visitor pattern and throw NotSupportedExceptions for the derived classes that have no importance or could be used by mistake.

    • coreycoogan said

      I would avoid implementing an interface and then not implementing them. This is a violation of the Interface Segregation Principal, which states that a classes should depend on the smallest possible interface.

      You could potentially use the Strategy pattern and define which strategy is going to be used at runtime. Then you know you are calling on only the strategy implementation you need.

      • Fathom Savvy said

        Thanks Corey. You are correct. I just had the opportunity to use the Visitor Pattern in a real world (for work) system. I used your article as a reference 🙂 You were right, I didn’t have to define an interface with members that did nothing in some classes. I don’t know what I was thinking. I remember using reflector to see how Fluent Nhibernate worked. I saw it was using the visitor pattern, but I didn’t understand it at the time. Now I have a better idea.

Sorry, the comment form is closed at this time.

 
%d bloggers like this: