namespace PatternsConsole
{
class VisitorPattern
{
// Visitor
public abstract class Visitor
{
public void ReflectiveVisit( Element element )
{
var types = new[] { element.GetType() };
var methodInfo = GetType().GetMethod( "Visit", types );
if ( methodInfo != null )
{
methodInfo.Invoke( this, new object[] { element } );
}
}
}
// Element
public abstract class Element
{
public abstract void Accept( Visitor visitor );
}
// ConcreteElement
class Person : Element
{
public string Name { get; set; }
public string Designation { get; set; }
public double Salary { get; set; }
public Person( string name, string designation, double salary )
{
Name = name;
Designation = designation;
Salary = salary;
}
public override void Accept( Visitor visitor )
{
visitor.ReflectiveVisit( this );
}
}
// ElementType
class Developer : Person
{
public Developer( string name, double salary ) :
base( name, "Developer", salary )
{
}
}
// ElementType
class Tester : Person
{
public Tester( string name, double salary ) :
base( name, "Tester", salary )
{
}
}
// ConcreteVisitor
class SalaryVisitor : Visitor
{
public void Visit( Developer developer )
{
VisitMethod( developer );
}
public void Visit( Tester tester )
{
VisitMethod( tester );
}
private static void VisitMethod( Element element )
{
var employee = element as Person;
if ( employee != null )
{
employee.Salary *= 1.50;
Console.WriteLine( "{0} {1}'s new income: {2:C}",
employee.GetType().Name, employee.Name,
employee.Salary );
}
}
}
private static void Main()
{
// ObjectStructure
var people = new List<Person>();
var developer = new Developer( "Foo", 1000 );
var tester = new Tester( "Bar", 1500 );
people.Add( developer );
people.Add( tester );
foreach ( var person in people )
{
person.Accept( new SalaryVisitor() );
}
//Output: Developer Foo's new income: $1,500.00
// Tester Bar's new income: $2,250.00
Console.ReadLine();
}
}
}