• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-20  評論-0  文章-0  trackbacks-0

              1.概述

                 組合模式有時候又叫做部分-整體模式,它使我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以向處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。

                 組合模式(Composite Pattern):將對象組合成樹形結構以表示‘部分-整體’的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。

                 組合模式結構圖如下:

                 結構圖說明:

                 (1)Component:組合中的對象聲明接口,在適當情況下實現所有類共有的默認行為,聲明一個接口用于訪問和管理Component的子組件。在遞歸結構中定義一個接口,用于訪問一個父部件,并在合適的情況下實現它。(可選)

                 (2)Leaf:在組合中表示葉節點,葉節點沒有子節點,定義對象的基本行為。

                 (3)Composite:定義有子部件的那些部件的行為,存儲子部件并在Component接口實現與子部件有關的操作。

                 (4)Client:通過Component接口操作組合部件的對象。

                 組合模式基本代碼:

                public abstract class Component
                {
                    protected string name;

                    public Component(string name)
                    {
                        this.name = name;
                    }

                    public abstract void Add(Component c);
                    public abstract void Remove(Component c);
                    public abstract void Display(int depth);
                }

                 Composite:

            public class Composite : Component
                {
                    private List<Component> children = new List<Component>();

                    public Composite(string name)
                        : base(name)
                    { }

                    public override void Add(Component c)
                    {
                        children.Add(c);
                    }

                    public override void Remove(Component c)
                    {
                        children.Remove(c);
                    }

                    public override void Display(int depth)
                    {
                        Console.WriteLine(new String('-', depth) + name);

                        foreach (Component component in children)
                        {
                            component.Display(depth + 2);
                        }
                    }
                }

                 Leaf:

                public class Leaf : Component
                {
                    public Leaf(string name)
                        : base(name)
                    { }

                    public override void Add(Component c)
                    {
                        Console.WriteLine("Cannot add to a leaf");
                    }

                    public override void Remove(Component c)
                    {
                        Console.WriteLine("Cannot remove from a leaf");
                    }

                    public override void Display(int depth)
                    {
                        Console.WriteLine(new String('-', depth) + name);
                    }
                }
            客戶端:
                public class Program
                {
                    static void Main(string[] args)
                    {
                        Composite root = new Composite("root");
                        root.Add(new Leaf("Leaf A"));
                        root.Add(new Leaf("Leaf B"));

                        Composite comp = new Composite("Composite X");
                        comp.Add(new Leaf("Leaf XA"));
                        comp.Add(new Leaf("Leaf XB"));

                        root.Add(comp);

                        Composite comp2 = new Composite("Composite XY");
                        comp2.Add(new Leaf("Leaf XYA"));
                        comp2.Add(new Leaf("Leaf XYB"));

                        comp.Add(comp2);

                        root.Add(new Leaf("Leaf C"));

                        Leaf leaf = new Leaf("Leaf D");
                        root.Add(leaf);
                        root.Remove(leaf);

                        root.Display(1);

                        Console.Read();
                    }
                }

                 可以看出,Composite類型的對象可以包含其它Component類型的對象。換而言之,Composite類型對象可以含有其它的樹枝(Composite)類型或樹葉(Leaf)類型的對象。

                 組合模式的實現根據所實現接口的區別分為兩種形式,分別稱為安全模式和透明模式。組合模式可以不提供父對象的管理方法,但組合模式必須在合適的地方提供子對象的管理方法(諸如:add、remove等)。安全式的組合模式要求管理聚集的方法只出現在樹枝構件類中,而不出現在樹葉構件中。與安全式的組合模式不同的是,透明式的組合模式要求所有的具體構件類,不論樹枝構件還是樹葉構件,均符合一個固定的接口。

                 透明模式:也就是說在Component中聲明所有用來管理子對象的方法,其中包括Add、Remove等。這樣實現Component接口的所有子類都具備了Add和Remove。這樣做的好處就是葉節點和枝節點對于外界沒有區別,它們具有完全一致的行為接口,但問題也很明顯,因為Leaf類本身不具備Add(),Remove()方法的功能,所以實現他是沒有意義的。

                 安全模式:就是在Component接口中不去聲明Add和Remove方法,那么子類的Leaf也就不需要去實現它,而是在Composite聲明所有用來管理子類對象的方法,這樣就不會出現透明模式出現的問題,不過由于不夠透明,所以葉節點和枝節點將不具有相同的接口,客戶端調用需要做相應的判斷,帶來了不便。

                 2.實例(大話設計模式)

                 大話設計模式中的公司管理系統的結構圖如下:

                 具體實現代碼如下:

            CompanyComposite
              public 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();//履行職責

                }

                public 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();
                        }
                    }

                }

                //人力資源部
                public 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);
                    }
                }

                //財務部
                public class FinanceDepartment : Company
                {
                    public FinanceDepartment(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);
                    }

                }

                 客戶端代碼:

            Code
             public class Program
                {
                    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();
                    }
                }

                 在.NET中,一個典型的組合模式實例就是.NET的控件,如Button,TextBox和Label等,這些控件都是繼承自Control類,該類自身包含ControlCollection的集合Controls,控件和子控件的邏輯關系如下圖:

             

                 3.總結

                 何時采用組合模式:

                 1.需求重要體現部分與整體的層次結構時

                 2.你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。

                 使用效果:

                 1.Composite模式采用樹形結構來實現普遍存在的對象容器,從而將“一對多”的關系轉化“一對一”的關系,使得客戶代碼可以一致地處理對象和對象容器,無需關心處理的是單個的對象,還是組合的對象容器。
                 2.將“客戶代碼與復雜的對象容器結構”解耦是Composite模式的核心思想,解耦之后,客戶代碼將與純粹的抽象接口——而非對象容器的復內部實現結構——發生依賴關系,從而更能“應對變化”。
                 3.Composite模式中,是將“Add和Remove等和對象容器相關的方法”定義在“表示抽象對象的Component類”中,還是將其定義在“表示對象容器的Composite類”中,是一個關乎“透明性”和“安全性”的兩難問題,需要仔細權衡。這里有可能違背面向對象的“單一職責原則”,但是對于這種特殊結構,這又是必須付出的代價。ASP.NET控件的實現在這方面為我們提供了一個很好的示范。
                 4.Composite模式在具體實現中,可以讓父對象中的子對象反向追溯;如果父對象有頻繁的遍歷需求,可使用緩存技巧來改善效率。

                 參考資料:

                  大化設計模式

                 http://terrylee.cnblogs.com/archive/2006/03/11/347919.html

            原帖地址:

            http://www.cnblogs.com/peida/archive/2008/09/09/1284686.html


            posted on 2016-02-14 14:36 Magic 閱讀(275) 評論(0)  編輯 收藏 引用 所屬分類: C/C++ 、java 、設計模式
            久久亚洲春色中文字幕久久久| 久久人人爽人人人人片av| 国产精品久久久久…| 精品久久久久久无码人妻蜜桃| 久久精品国产亚洲Aⅴ香蕉| 精品国产乱码久久久久久人妻| 国产综合久久久久久鬼色| 欧美大战日韩91综合一区婷婷久久青草| 久久精品一本到99热免费| 久久最近最新中文字幕大全 | 欧美精品丝袜久久久中文字幕 | 国产精品久久久久9999| 久久精品夜色噜噜亚洲A∨| 色婷婷久久综合中文久久蜜桃av| 香蕉久久一区二区不卡无毒影院 | 久久精品国产精品亚洲艾草网美妙| 精品久久久久久中文字幕大豆网| 国产日韩久久免费影院| 国产成年无码久久久久毛片| 日韩欧美亚洲国产精品字幕久久久 | 99久久免费国产精精品| 久久亚洲AV无码西西人体| 99久久99久久| 久久久久女人精品毛片| 中文字幕亚洲综合久久菠萝蜜| 精品无码久久久久国产| 亚洲精品无码久久久久| 国内精品久久久久影院亚洲| 久久人妻少妇嫩草AV蜜桃| 青青青国产精品国产精品久久久久| 无码国产69精品久久久久网站| 伊人热热久久原色播放www| 久久久国产精品网站| 秋霞久久国产精品电影院| 国内精品久久久久| 日本久久久久久中文字幕| 欧美伊香蕉久久综合类网站| 久久精品草草草| 精品久久久久久国产牛牛app| 精品久久久久久久久久中文字幕 | 国产精品亚洲美女久久久|