Register | Login 
View Article  

Current Articles | Categories | Search | Syndication

Implementing the Visitor Design Pattern In .Net

By John Spano on Tuesday, February 21, 2006 :: 882 Views :: 1 Comments :: :: Design Patterns

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 use our common Cbulldog object for our example.
 
[code]
            public class BaseVisitor
            {
                        public BaseVisitor()
                        {
                        }
                        virtual public void VisitBulldog(CBulldog dog)
                        {
                        }
            }
[/code]
 
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, 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;}
                        }
            }
[/code]
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;
            }
 
      }
[/code]
 
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";
            }
      }
[/code]
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();
[/code]
 
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.

Previous Page | Next Page

COMMENTS

So Nice

posted @ Friday, February 16, 2007 3:51 AM by baijnath


Click here to post a comment

Copyright (c) 2008 GSP Developers
Walling Info Systems | Terms Of Use | Privacy Statement