Last active
May 4, 2018 04:26
-
-
Save asarnaout/1ef19a9417056d1e239c0d3173737672 to your computer and use it in GitHub Desktop.
Visitor Design Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Visitor | |
{ | |
public interface IVisitor | |
{ | |
void Visit(IVisitable visitable, params object[] arg); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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