Skip to content

Instantly share code, notes, and snippets.

@asarnaout
Last active May 4, 2018 04:26
Show Gist options
  • Save asarnaout/1ef19a9417056d1e239c0d3173737672 to your computer and use it in GitHub Desktop.
Save asarnaout/1ef19a9417056d1e239c0d3173737672 to your computer and use it in GitHub Desktop.
Visitor Design Pattern
namespace Visitor
{
class Program
{
/*
* The Visitor pattern allows you to define new operations on a type without changing the type itself.
*/
static void Main(string[] args)
{
var employee = new Employee
{
Name = "Ahmed",
Salary = 10000,
DaysTakenOff = 0
};
employee.TakeVacation(14);
Console.WriteLine(employee.Salary);
var vacationVisitor = new VacationCalculator();
/*
* Here we defined a new operation on the IVisitable 'Employee' type by the IVisitor 'VacationCalculator' type without
* modifying the 'Employee' type,
*/
employee.Accept(vacationVisitor);
Console.WriteLine(employee.Salary);
Console.ReadLine();
}
}
}
namespace Visitor
{
public interface IVisitable
{
/*
* Types that require new operations without modification should implement the IVisitable interface to accept incoming
* IVisitor(s) that will perform these operations
*/
void Accept(IVisitor visitor);
}
}
namespace Visitor
{
public class Employee : IVisitable
{
public string Name { get; set; }
public double Salary { get; set; }
public int DaysTakenOff { get; set; }
public void Accept(IVisitor visitor) //The IVisitor's Visit method is called with relevant parameters
{
visitor.Visit(this);
}
public override string ToString()
{
return $"Employee Name: {Name}, Salary: {Salary}, has taken {DaysTakenOff} days off this year.";
}
public void TakeVacation(int vacationDays) => DaysTakenOff += vacationDays;
}
}
namespace Visitor
{
public interface IVisitor
{
void Visit(IVisitable visitable, params object[] arg);
}
}
namespace Visitor
{
public class VacationCalculator : IVisitor
{
const int MaximumVacationDaysPerYear = 10;
public void Visit(IVisitable visitable, params object[] arg)
{
if (visitable is Employee employee)
{
var daysTakenOff = employee.DaysTakenOff;
var employeeSalary = employee.Salary;
if (daysTakenOff > MaximumVacationDaysPerYear)
{
employee.Salary -= (employeeSalary * (((double)daysTakenOff - MaximumVacationDaysPerYear) / 365));
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment