• <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.概述

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

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

                 組合模式結(jié)構(gòu)圖如下:

                 結(jié)構(gòu)圖說明:

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

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

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

                 (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)類型的對象。

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

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

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

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

                 大話設(shè)計模式中的公司管理系統(tǒng)的結(jié)構(gòu)圖如下:

                 具體實現(xiàn)代碼如下:

            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結(jié)構(gòu)圖:");

                        root.Display(1);

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

                        root.LineOfDuty();


                        Console.Read();
                    }
                }

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

             

                 3.總結(jié)

                 何時采用組合模式:

                 1.需求重要體現(xiàn)部分與整體的層次結(jié)構(gòu)時

                 2.你希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。

                 使用效果:

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

                 參考資料:

                  大化設(shè)計模式

                 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 閱讀(289) 評論(0)  編輯 收藏 引用 所屬分類: C/C++java設(shè)計模式
            99久久香蕉国产线看观香| 亚洲国产成人久久一区久久| 久久亚洲日韩精品一区二区三区| 色婷婷久久综合中文久久一本| 国产精自产拍久久久久久蜜| 国产999精品久久久久久| 国产高潮国产高潮久久久91| 精品久久人人爽天天玩人人妻| 国产午夜电影久久| 亚洲国产精品综合久久一线 | 久久婷婷五月综合国产尤物app| 久久影院亚洲一区| 2019久久久高清456| 国产aⅴ激情无码久久| 97久久久精品综合88久久| 久久精品国产亚洲一区二区| 久久久国产一区二区三区| 精品久久久久成人码免费动漫 | 丁香五月网久久综合| 99久久精品费精品国产 | 久久精品国产亚洲77777| 国产精品免费久久| 国产香蕉久久精品综合网| 国产91久久精品一区二区| 丰满少妇人妻久久久久久4| 国内精品久久国产| 97久久久久人妻精品专区| 午夜视频久久久久一区| 精品999久久久久久中文字幕| 久久99久久无码毛片一区二区| 一本色道久久综合狠狠躁| 成人亚洲欧美久久久久 | 精品国产婷婷久久久| 无码人妻少妇久久中文字幕蜜桃| 国产视频久久| 996久久国产精品线观看| 久久精品卫校国产小美女| 国产日韩久久免费影院| 久久精品www| 91精品国产综合久久精品| 色播久久人人爽人人爽人人片AV |