/// <summary>
/// using this pattern, the concrete element such as Family or Team is supposed to be stable,
/// and the count of the total elements should be stable as well.
/// Concrete visitor such as CompeteNotice or FeeCharge, may be extendable. For instance, we
/// can add a GroupPrincalChagingNotice easily in the future.
/// </summary>
class VisitorPattern
{
public static void Main()
{
List<IGroup> groups = new List<IGroup>();
groups.Add(new Team("火箭"));
groups.Add(new Team("太阳战队"));
groups.Add(new Family("幸福之家"));
groups.Add(new Workroom("逍遥派"));
IVisitor visitor = new CompeteNotice();
foreach (var group in groups)
{
Console.WriteLine("-----------------{0} to {1}----------------", visitor.VisitorName, group.GroupName);
group.Accept(visitor);
Console.WriteLine();
}
}
#region Visitor
interface IVisitor
{
string VisitorName { get; }
void VisitFamily(Family family);
void VisitTeam(Team team);
void VisitWorkroom(Workroom workroom);
}
class CompeteNotice : IVisitor
{
public string VisitorName
{
get { return "比赛通知"; }
}
//Just EMail to parents
public void VisitFamily(Family family)
{
foreach (var person in family.Persons)
{
if (person.IsParent)
{
Console.WriteLine("send email to {0} with mobile {1}", person.EMail, person.EMail);
}
}
}
//EMail to every member and Send SMS to the Princal
public void VisitTeam(Team team)
{
foreach (var person in team.Persons)
{
Console.WriteLine("send email to {0} with EMail {1}", person.EMail, person.EMail);
if (person.IsPrincipal)
{
Console.WriteLine("send SMS to {0} with mobile {1}", person.EMail, person.Mobilephone);
}
}
}
//EMail and Send SMS to the Princal
public void VisitWorkroom(Workroom workroom)
{
foreach (var person in workroom.Persons)
{
if (person.IsPrincipal)
{
Console.WriteLine("send email to {0} with EMail {1}", person.EMail, person.EMail);
Console.WriteLine("send SMS to {0} with mobile {1}", person.EMail, person.Mobilephone);
}
}
}
}
class FeeCharge : IVisitor
{
private decimal _totalFees = 1000;
private decimal _overheadFees = 5;
//charge parents for both _totalFees and _overheadFees
public void VisitFamily(Family family)
{
throw new NotImplementedException();
}
//charge each one for _totalFees and charge principal for _overheadFees
public void VisitTeam(Team team)
{
throw new NotImplementedException();
}
//charge principal for both _totalFees and _overheadFees
public void VisitWorkroom(Workroom workroom)
{
throw new NotImplementedException();
}
public string VisitorName
{
get { return "收取费用"; }
}
}
//class PrincipalChanging : IVisitor
#endregion
#region Element
interface IGroup
{
string GroupName { get; }
Person[] Persons { get; }
void Accept(IVisitor visitor);
}
class Family : IGroup
{
private string _name;
public Family(string name)
{
_name = name;
}
public string GroupName
{
get { return _name; }
}
public Person[] Persons
{
get { return GetTestData(); }
}
public void Accept(IVisitor visitor)
{
visitor.VisitFamily(this);
}
}
class Team : IGroup
{
private string _name;
public Team(string name)
{
_name = name;
}
public string GroupName
{
get { return _name; }
}
public Person[] Persons
{
get { return GetTestData(); }
}
public void Accept(IVisitor visitor)
{
visitor.VisitTeam(this);
}
}
class Workroom : IGroup
{
private string _name;
public Workroom(string name)
{
_name = name;
}
public string GroupName
{
get { return _name; }
}
public Person[] Persons
{
get { return GetTestData(); }
}
public void Accept(IVisitor visitor)
{
visitor.VisitWorkroom(this);
}
}
#endregion
#region non-essential statements
static Person[] GetTestData()
{
var persons = new Person[]
{
new Person(){ Name="Jim1", EMail="Jim1@hotmail.com", BankAccout="62218888888888881", Mobilephone="138666666661", IsParent=false, IsPrincipal=false},
new Person(){ Name="Jim2", EMail="Jim2@hotmail.com", BankAccout="62218888888888882", Mobilephone="138666666662", IsParent=true, IsPrincipal=true},
new Person(){ Name="Jim3", EMail="Jim3@hotmail.com", BankAccout="62218888888888883", Mobilephone="138666666663", IsParent=true, IsPrincipal=false},
};
return persons;
}
class Person
{
public string Name { get; set; }
public string Mobilephone { get; set; }
public string BankAccout { get; set; }
public string EMail { get; set; }
public bool IsParent { get; set; }
public bool IsPrincipal { get; set; }
}
#endregion
}