Visitor Design Pattern in c#
Visitor pattern is a part of behavioral design pattern. Visitor pattern will not change the current code structure It is used to add the new functionality in existing code. Classes which holds the new behaviors are commonly known as Visitors.
Visitor pattern promotes code separation, single responsibility principle & it also enforce the Open Close Principle.
Visitor pattern promotes code separation, single responsibility principle & it also enforce the Open Close Principle.
Key Participants
- Visitor - It declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class.
- ConcreteVisitor -It implements each operation declared by Visitor.
- Element- It defines an Accept operation that takes a visitor as an argument.
- ConcreteElement -It implements an Accept operation that takes a visitor as an argument.
- ObjectStructure- It holds all the element of the data structure as a collection, list or something which can be enumerated and used by the visitors.
Code Sample
Let's take an example Where a program will calculate the price and quantity Food. Now You may find yourself in a situation where you need to make a functional change in price and quantity to a collection of classes but you do not have control over the classes in the hierarchy. This is where the Visitor pattern comes in. The intent of the Visitor design pattern is to define a new operation for a collection of classes (that is the classes being visited) without changing the hierarchy itself.
Here food price should increase by 10% and quantity need to increase by 3.
Let's take an example Where a program will calculate the price and quantity Food. Now You may find yourself in a situation where you need to make a functional change in price and quantity to a collection of classes but you do not have control over the classes in the hierarchy. This is where the Visitor pattern comes in. The intent of the Visitor design pattern is to define a new operation for a collection of classes (that is the classes being visited) without changing the hierarchy itself.
Here food price should increase by 10% and quantity need to increase by 3.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace VisitorPattern.Sample { class Program { /// <summary> /// Entry point into console application. /// </summary> static void Main() { // Setup food collection var food = new FastFood(); food.Attach(new Pizza()); food.Attach(new Pasta()); food.Attach(new Burger()); // food are 'visited' food.Accept(new PriceVisitor()); food.Accept(new QuantityVisitor()); // Wait for user Console.ReadKey(); } } /// <summary> /// The 'Visitor' abstract class /// </summary> public abstract class Visitor { // Use reflection to see if the Visitor has a method // named Visit with the appropriate parameter type // (i.e. a specific Food). If so, invoke it. public void ReflectiveVisit(IElement element) { var types = new Type[] { element.GetType() }; var mi = this.GetType().GetMethod("Visit", types); if (mi != null) { mi.Invoke(this, new object[] { element }); } } } /// <summary> /// A 'ConcreteVisitor' class /// </summary> class PriceVisitor : Visitor { // Visit clerk public void Visit(Pizza clerk) { DoVisit(clerk); } // Visit director public void Visit(Pasta director) { DoVisit(director); } private void DoVisit(IElement element) { var food = element as Food; // Provide 10% price raise food.Price *= 1.10; Console.WriteLine("{0} {1}'s new price: {2:C}", food.GetType().Name, food.Name, food.Price); } } /// <summary> /// A 'ConcreteVisitor' class /// </summary> class QuantityVisitor : Visitor { // Visit director public void Visit(Pasta director) { DoVisit(director); } private void DoVisit(IElement element) { var food = element as Food; // Provide 3 extra quantity food.Quantity += 3; Console.WriteLine("{0} {1}'s new quantity: {2}", food.GetType().Name, food.Name, food.Quantity); } } /// <summary> /// The 'Element' interface /// </summary> public interface IElement { void Accept(Visitor visitor); } /// <summary> /// The 'ConcreteElement' class /// </summary> class Food : IElement { // Constructor public Food(string name, double price, int quantity) { this.Name = name; this.Price = price; this.Quantity = quantity; } // Gets or sets name public string Name { get; set; } // Gets or set price public double Price { get; set; } // Gets or sets Quantity days public int Quantity { get; set; } public virtual void Accept(Visitor visitor) { visitor.ReflectiveVisit(this); } } /// <summary> /// The 'ObjectStructure' class /// </summary> class FastFood : List<Food> { public void Attach(Food food) { Add(food); } public void Detach(Food food) { Remove(food); } public void Accept(Visitor food) { // Iterate over all fastfood and accept visitor this.ForEach(item => item.Accept(food)); Console.WriteLine(); } } // Three Food types class Pizza : Food { // Constructor public Pizza() : base("Veggie Pizza", 100.0, 10) { } } class Pasta : Food { // Constructor public Pasta() : base("Corn Pasta", 50.0, 5) { } } class Burger : Food { // Constructor public Burger() : base("Veg Burger", 20.0, 25) { } } }
0 comments :
Post a Comment