Gang of Four (GOF) Design Patterns
page 3 of 8
by John Spano
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 39607/ 74

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 in which normal polymorphism will not 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 structure 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 is 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.

Listing 9

public class BaseVisitor
{
  public BaseVisitor(){}
  virtual public void VisitBulldog(CBulldogdog){}
}

The code 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 we will look at our Cbulldog class.  It has not changed much; there is only one new method.

Listing 10

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 simply calls 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:

Listing 11

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

 Listing 12 is the class that will change his bark.

Listing 12

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

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

Our test code for the example:

Listing 13

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.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-24 12:56:14 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search