NeoTekSystems Blog

This Blog is hosted and monitored by NeoTekSystems and its staff.
All programmers and business representatives are welcome
to stop by and participate in discussions about the .NET framework.
Welcome to NeoTekSystems Blog Sign in | Join | Help
in Search

Implementating the Visitor Design Pattern

Last post 02-11-2007, 1:33 PM by joejoe. 1 replies.
Sort Posts: Previous Next
  •  06-07-2005, 8:09 PM 15

    Implementating the Visitor Design Pattern

    Implementing the Visitor Design Pattern In .Net

    Level: Intermediate to Object Oriented Programming; Beginner + with .NET and C#

        The visitor design pattern is very useful in situations where normal polymorphism won’t work because we have fundamentally different objects, with different interfaces, that you want to work on your concrete main object. The pattern is used to give us a way to do these different operations on the object. According to the GOF book, you use the visitor pattern when:

        1. An object structure contains many classes of objects with differing interfaces, and you want to perform          operations on these objects that depend on their concrete classes.
        2. Many distinct and unrelated operations need to be performed on objects in an object structore, and you want     to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by     defining them in one class. When the object structure is shared by many applications, use Visitor to put     operations in just those applications that need them.
        3. The classes defining the object structure rarely change, but you often want to define new operations over the     structure. Changing the object structure classes requires redefining the interface to all visitors, which is     potentially costly, if the object structure classes change often, then it's probably better to define the operations in     those classes.[GOF333]

        We first start by defining a base class for our visitor object collection. We will also use our common Cbulldog object for our example.


    Code:

        public class BaseVisitor
        {
            public BaseVisitor()
            {
            }
            virtual public void VisitBulldog(CBulldog dog)
            {
            }
        }


    It is pretty simple, having only a single method that takes an instance of the bulldog to work on. We can then derive concrete instances of visitors from this base. We will derive two for our example, one that changes our dog’s age and another that changes his bark. First a look at our Cbulldog class. It hasn’t change much from our other examples, there is only one new method.

    Code:

        public class CBulldog
        {
            private int _Age;
            private string _BarkString;
            public CBulldog()
            {
                _Age = 0;
                _BarkString = "Woof";
            }
            public void TakeVisitor(BaseVisitor bv)
            {
                bv.VisitBulldog(this);
            }
            public void Bark()
            {
                Console.WriteLine(_BarkString);
            }
            public int MyAge
            {
                get{return _Age;}
                set{_Age = value;}
            }
            public string MyBark
            {
                get{return _BarkString;}
                set{_BarkString = value;}
            }
        }


    The TakeVisitor method allows our class to accept any visitor that is derived from BaseVisitor. The method simple calles the VisitBulldog method and passes a pointer to the current class.

        Now we look at our concrete derived visitor classes. First the class that will change the dog’s age:

    Code:

        public class AgeVisitor : BaseVisitor
        {
            public AgeVisitor() : base()
            {
            }
            public override void VisitBulldog(CBulldog dog)
            {
                dog.MyAge = 5;
            }

        }


    And then the class that will change his bark:

    Code:

        public class BarkVisitor : BaseVisitor    
        {
            public BarkVisitor() : base()
            {
            }
            public override void VisitBulldog(CBulldog dog)
            {
                dog.MyBark = "Yip Yip";
            }
        }


    As you see, all the methods do is act upon the dog object passed to them. You can make them as complex or simple as needed.

        Our test code for the example:

    Code:

            CBulldog Mydog;
            Mydog = new CBulldog();

            Mydog.Bark();
            Console.WriteLine(Mydog.MyAge.ToString());

            AgeVisitor av;
            av = new AgeVisitor();
            Mydog.TakeVisitor(av);
            Console.WriteLine(Mydog.MyAge.ToString());

            BarkVisitor bv;
            bv = new BarkVisitor();
            Mydog.TakeVisitor(bv);
            Mydog.Bark();


    If you watch the output window, you will see that the calls to TakeVisitor change the dog’s information.

        This pattern can help keep your objects cleaner when there are many different types of visitors you want to use. It allows for an infinate number of visitors to be passed to the CBulldog class. If you decide you need a different one in the future, just create a new object and pass it to the TakeVisitor method. No changes are necessary to the CBulldog class.

    John Spano
    President
    NeoTekSystems, Inc.
    www.NeoTekSystems.com
    Microsoft MVP, MCSD, MCTS-Windows, MCTS-Web, MCPD-Distributed, MCITP-SQLDev, MCITP-SQLAdmin
  •  02-11-2007, 1:33 PM 89 in reply to 15

    Re: Implementating the Visitor Design Pattern

    see the Visitor Pattern using reflection example on oodesign.com
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems