close

What is the Visitor Design Pattern ?

1. Allows you to add methods to classes of different types without much altering to these classes.

2. You can make completely different methods depending on the class used.

3. Allows you to define external classes that can extend other classes without majorly edit them.

image

Liquor Class:

   1: public class Liquor
   2: {
   3: }

Tobacco Class:

   1: public class Tobacco
   2: {
   3: }

Necessity Class:

   1: public class Necessity
   2: {
   3: }

IVisitor Interface:

In order to add some external methods to these visitable classes, such as Liquor, Tobacco and Necessiy Class.

   1: public interface IVisitor
   2: {
   3:  double visitor(Liquor l);
   4:  double visitor(Tobacco t);
   5:  double visitor(Necessity n);
   6: }

TaxVisitor Class:

To give the specific methods for these visitable classes, such as Liquor, Tobacco and Necessiy Class.

   1: public class TaxVisitor : IVisitor
   2: {
   3:    public double visitor(Liquor liquorItem)
   4:    {
   5:        Console.WriteLine("Liquor item: Price with Tax");
   6:        return liquorItem.GetPrice() * .18 + liquorItem.GetPrice();
   7:    }
   8:  
   9:    public double visitor(Tobacco tobaccoItem)
  10:    {
  11:        Console.WriteLine("Tobacco item: Price with Tax");
  12:        return tobaccoItem.GetPrice() * .32 + tobaccoItem.GetPrice();
  13:    }
  14:  
  15:    public double visitor(Necessity necessityItem)
  16:    {
  17:        Console.WriteLine("Necessity item: Price with Tax");
  18:        return necessityItem.GetPrice() * 0 + necessityItem.GetPrice();
  19:    }
  20: }

IVisitable Interface:

   1: interface IVisitable
   2: {
   3:     double accept(IVisitor visitor);
   4: }

Again go back to Liquor Class and update it

Liquor Class:

   1: public class Liquor : IVisitable
   2: {
   3:     private double price;
   4:     public Liquor(double price)
   5:     {
   6:         this.price = price;
   7:     }
   8:     public double GetPrice()
   9:     {
  10:         return price;
  11:     }
  12:     public double accept(IVisitor visitor)
  13:     {
  14:         throw new NotImplementedException();
  15:     }
  16: }

Tobacco Class:

   1: public class Tobacco:IVisitable
   2:  {
   3:      private double price;
   4:      public Tobacco(double price)
   5:      {
   6:          this.price = price;
   7:      }
   8:      public double GetPrice()
   9:      {
  10:          return price;
  11:      }
  12:      public double accept(IVisitor visitor)
  13:      {
  14:          throw new NotImplementedException();
  15:      }
  16:  }

Necessity Class:

   1: public class Necessity:IVisitable
   2: {
   3:   private double price;
   4:   public Necessity(double price)
   5:   {
   6:       this.price = price;
   7:   }
   8:  
   9:   public double GetPrice()
  10:   {
  11:       return price;
  12:   }
  13:   public double accept(IVisitor visitor)
  14:   {
  15:       throw new NotImplementedException();
  16:   }
  17: }

Now we are going to focus on the accept method for each sub-class of IVisitable, including Liquor, Tobacco, and Necessity Class.

Copy and paste the following snippet to replace all accept methods mentioned above with it.

This is very important that it passes a visitor to its input argument, and also introduce itself to the vistor.

The visitor can visit the visitable instance by using the way like this: visitor.visitor(this) that extends visible classes without majorly edit them.

Some methods are added to those visitable classes, which are carried by the visitors.

   1: public double accept(IVisitor visitor)
   2: {
   3:     return visitor.visitor(this);
   4: }

Then we are going to introduce anthor type of visitor that provide special hoilday tax.

So let us copy TaxVisitor first and paste them in TaxHoliday Class.

What we need to do is simply to reduce the values of tax.

To give another types of specific methods for these visitable classes, such as Liquor, Tobacco and Necessiy Class.

   1: class TaxHolidayVisitor
   2: {
   3:     public double visitor(Liquor liquorItem)
   4:     {
   5:         Console.WriteLine("Liquor item: Price with Tax");
   6:         return liquorItem.GetPrice() * .10 + liquorItem.GetPrice();
   7:     }
   8:  
   9:     public double visitor(Tobacco tobaccoItem)
  10:     {
  11:         Console.WriteLine("Tobacco item: Price with Tax");
  12:         return tobaccoItem.GetPrice() * .30 + tobaccoItem.GetPrice();
  13:     }
  14:  
  15:     public double visitor(Necessity necessityItem)
  16:     {
  17:         Console.WriteLine("Necessity item: Price with Tax");
  18:         return necessityItem.GetPrice() * 0 + necessityItem.GetPrice();
  19:     }
  20: }

Finally we are ready to code the main program like this:

   1: static void Main(string[] args)
   2: {
   3:     TaxVisitor taxCalc = new TaxVisitor();
   4:     TaxHolidayVisitor taxHolidayCalc = new TaxHolidayVisitor();
   5:  
   6:     Necessity milk = new Necessity(3.47);
   7:     Liquor vodka = new Liquor(11.99);
   8:     Tobacco cigars = new Tobacco(19.99);
   9:  
  10:     Console.WriteLine("{0:#.##}", milk.accept(taxCalc));
  11:     Console.WriteLine("{0:#.##}", vodka.accept(taxCalc));
  12:     Console.WriteLine("{0:#.##}", cigars.accept(taxCalc));
  13:  
  14:     Console.WriteLine("{0:#.##}", milk.accept(taxHolidayCalc));
  15:     Console.WriteLine("{0:#.##}", vodka.accept(taxHolidayCalc));
  16:     Console.WriteLine("{0:#.##}", cigars.accept(taxHolidayCalc));
  17:     Console.ReadKey();    
  18: }
image

1. Allows you to add methods to classes of different types without much altering to these classes.

classes of different types are Liquor, Tobacco and Necessity Classes.

image

For TaxVisitor, some methods, which are highlights with red retangles, are added to classes of different types such as Liquor, Tobacco and Necessity Classes.

image

2. You can make completely different methods depending on the class used.

depending on the class used: here we got two different classes, they are TaxVisitor and TaxHolidyVistor

different methods: it means that completely differnt methods are encapsulated in TaxVisitor and TaxHolidyVistor

3. Allows you to define external classes that can extend other classes without majorly edit them.

external classes: it means TaxVisitor and TaxHolidyVistorthey

extend other classes: it means IVisitable sub-classes, they are Liquor, Tobacco and Necessity Classes

image

 

 

 

References:

1. Visitor Design Pattern

arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(0) 人氣()