/// <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 }