using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Visitor.RealWorld
{
///
/// MainApp startup class for Real-World
/// Visitor Design Pattern.
///
class MainApp
{
///
/// Entry point into console application.
///
static void Main()
{
// Setup employee collection
Employees e = new Employees();
e.Attach(new Clerk());
e.Attach(new Director());
e.Attach(new President());
// Employees are 'visited'
e.Accept(new IncomeVisitor());
e.Accept(new VacationVisitor());
// Wait for user
Console.ReadKey();
}
}
///
/// The 'Visitor' interface
///
interface IVisitor
{
void Visit(Element element);
}
///
/// A 'ConcreteVisitor' class
///
class IncomeVisitor : IVisitor
{
public void Visit(Element element)
{
Employee employee = element as Employee;
// Provide 10% pay raise
employee.Income *= 1.10;
Console.WriteLine("{0} {1}'s new income: {2:C}",
employee.GetType().Name, employee.Name,
employee.Income);
}
}
///
/// A 'ConcreteVisitor' class
///
class VacationVisitor : IVisitor
{
public void Visit(Element element)
{
Employee employee = element as Employee;
// Provide 3 extra vacation days
employee.VacationDays += 3;
Console.WriteLine("{0} {1}'s new vacation days: {2}",
employee.GetType().Name, employee.Name,
employee.VacationDays);
}
}
///
/// The 'Element' abstract class
///
abstract class Element
{
public abstract void Accept(IVisitor visitor);
}
///
/// The 'ConcreteElement' class
///
class Employee : Element
{
private string _name;
private double _income;
private int _vacationDays;
// Constructor
public Employee(string name, double income, int vacationDays)
{
this._name = name;
this._income = income;
this._vacationDays = vacationDays;
}
// Gets or sets the name
public string Name
{
get { return _name; }
set { _name = value; }
}
// Gets or sets income
public double Income
{
get { return _income; }
set { _income = value; }
}
// Gets or sets number of vacation days
public int VacationDays
{
get { return _vacationDays; }
set { _vacationDays = value; }
}
public override void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
///
/// The 'ObjectStructure' class
///
class Employees
{
private List _employees = new List();
public void Attach(Employee employee)
{
_employees.Add(employee);
}
public void Detach(Employee employee)
{
_employees.Remove(employee);
}
public void Accept(IVisitor visitor)
{
foreach (Employee e in _employees)
{
e.Accept(visitor);
}
Console.WriteLine();
}
}
// Three employee types
class Clerk : Employee
{
// Constructor
public Clerk() : base("Hank", 25000.0, 14)
{
}
}
class Director : Employee
{
// Constructor
public Director() : base("Elly", 35000.0, 16)
{
}
}
class President : Employee
{
// Constructor
public President() : base("Dick", 45000.0, 21)
{
}
}
}