Design Pattern - Visitor Pattern

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

 

posted @ 2014-04-12 09:45  cnbwang  阅读(248)  评论(0编辑  收藏  举报