閱讀901 返回首頁    go 阿裏雲 go 技術社區[雲棲]


設計模式之部分-整體模式

      組合模式:

                 是將對象組合成樹形結構以表示‘部分-整體’的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。組合是對象的集合,而其中的任何一個對象又可能是一個組合,或者是一個簡單的對象。在樹形結構中,訪問組合中所有的對象要求有一個簡單的單一訪問接口,但同時要求能夠區分開節點和葉子。在構造組合的時候,我們需要決定哪個節點是元素哪個是葉子。在這裏我們可以通過子節點個數進行判斷是不是葉子節點。

            比如說一個公司,裏邊有經理,經理下邊有部門經理,部門經理下邊有小組負責人,小組負責人下邊有員工,這裏可以將這些人分為兩類,一類是雇員類(葉子節點),一類是老板類(有子節點)。這裏的葉子節點下麵是沒有分支的,而子節點則相當於樹枝,下麵有子節點,即屬於不同的層次的管理人員,這樣是明顯的組合-整體結構。通過舉例我們介紹一下組合模式結構圖。

      組合模式結構圖:

                

               例子:

               

 static void Main(string[] args)
        {
            ConcreteCompany root = new ConcreteCompany("北京總公司");
            root.Add(new HRDepartment("總公司人力資源部"));
            root.Add(new FinanceDepartment("總公司財務部"));

            ConcreteCompany comp = new ConcreteCompany("上海華東分公司");
            comp.Add(new HRDepartment("華東分公司人力資源部"));
            comp.Add(new FinanceDepartment("華東分公司財務部"));
            root.Add(comp);

            ConcreteCompany comp1 = new ConcreteCompany("南京辦事處");
            comp1.Add(new HRDepartment("南京辦事處人力資源部"));
            comp1.Add(new FinanceDepartment("南京辦事處財務部"));
            comp.Add(comp1);

            ConcreteCompany comp2 = new ConcreteCompany("杭州辦事處");
            comp2.Add(new HRDepartment("杭州辦事處人力資源部"));
            comp2.Add(new FinanceDepartment("杭州辦事處財務部"));
            comp.Add(comp2);

            Console.WriteLine("\n結構圖:");
            root.Display(1);

            Console.WriteLine("\n職責:");
            root.LineOfDuty();

            Console.Read();
        }
        //公司類 抽象類或接口
        abstract class Company
        {
            protected string name;
            public Company (string name)
            {
                this.name = name;
            }
            public abstract void Add(Company c);//增加
            public abstract void Remove(Company c);//移除
            public abstract void Display(int depth);//顯示
            public abstract void LineOfDuty();//履行職責:不同部門需履行不同的職責
        }
        //具體公司類 實現接口 樹枝節點
        class ConcreteCompany:Company
        {
            private List<Company> children = new List<Company>();
            public ConcreteCompany (string name)
                :base(name)
            { }
            public override void Add(Company c)
            {
                children.Add(c);
            }
            public override void Remove(Company c)
            {
                children.Remove(c);
            }
            public override void Display(int depth)
            {
                Console.WriteLine(new string('-', depth) + name);
                foreach (Company component in children )
                {
                    component.Display(depth + 2);
                }
            }
            //履行職責
            public override void LineOfDuty()
            {
                foreach (Company component in children )
                {
                    component.LineOfDuty();
                }
            }
        }
        //人力資源部與財務部類 樹葉節點
        //人力資源部
        class HRDepartment : Company
        {
            public HRDepartment (string name):base(name )
            { }
            public override void Add(Company c)
            { }
            public override void Remove(Company c)
            { }
            public override void Display(int depth)
            {
                Console.WriteLine(new string('-', depth) + name);
            }
            public override void LineOfDuty()
            {
                Console.WriteLine("{0}員工招聘培訓管理", name);
            }
        }
        //財務部
        class FinanceDepartment:Company
        {
            public FinanceDepartment (string name):base(name )
            { }
            public override void Add(Company c)
            { }
            public override void Remove(Company c)
            { }
            public override void LineOfDuty()
            {
                Console.WriteLine("{0}公司財務收支管理", name);
            }
            public override void Display(int depth)
            {
                Console.WriteLine(new string('-', depth) + name);
            }
        }

         適用性:

                           當發現需求中是體現部分與整體層次結構時,以及你希望用戶可以忽略組合對象與單個對象的不同,統一地使用組合結構中的所有對象時,就應該考慮組合模式了

               

最後更新:2017-04-03 12:55:07

  上一篇:go 設計模式六大原則--裏氏代換原則
  下一篇:go 設計模式六大原則--依賴倒轉原則