Thursday, 31 May 2018

Visitor Pattern

In the last post we saw how C# uses single-dispatch to select the methods to call. The argument type is determined at compile time and that is used to select the method out of many.

Here is an implementation of visitor pattern to resolve that problem:

void Main()
{
 Employee employee = new Employee();
 Employee manager = new Manager();

 IVisitor visitor = new SalaryAlgoPerformanceVisitor();
 
 employee.Accept(visitor);
 manager.Accept(visitor);
 
 Console.WriteLine(visitor.Output);
}

interface IVisitor
{
 string Output {get;}
 void Visit(Employee e);
 void Visit(Manager e);
}

class SalaryAlgoPerformanceVisitor : IVisitor
{
 public string Output { get; private set;}
 public void Visit(Employee e)
 {
  Output += $"Calculating salary of {nameof(Employee)} based on {nameof(SalaryAlgoPerformanceVisitor)}\n";
 }
 public void Visit(Manager e)
 {
  Output += $"Calculating salary of {nameof(Manager)} based on {nameof(SalaryAlgoPerformanceVisitor)}\n";
 }
}

class Employee
{
 public virtual string GetEmployeeType()
 {
  return nameof(Employee);
 }
 
 public virtual void Accept(IVisitor visitor)
 {
  visitor.Visit(this);
 }
}

class Manager : Employee
{
 public override string GetEmployeeType()
 {
  return nameof(Manager);
 }
 
 public override void Accept(IVisitor visitor)
 {
  visitor.Visit(this);
 }
}

Output:

Calculating salary of Employee based on SalaryAlgoPerformanceVisitor
Calculating salary of Manager based on SalaryAlgoPerformanceVisitor

You will notice that Accept method is resolved using the run time type of Employee object - this is the first dispatch. Then in the Accept method we use (this) so that appropriate method is called on the visitor - this is the second dispatch.

Since Accept is inside the class, we use the type of (this) to call the visitor.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.

C# Reactive Extensions - Buffer and Window

I was going through Buffer and Window in RX, thought a few examples would help clear the differences. First create a buffer of even numbe...