• <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>

            大龍的博客

            常用鏈接

            統計

            最新評論

            設計模式學習筆記(九)——Composite組合模式

                  Composite組合模式主要是應對這樣的問題:一類具有“容器特征”的對象——即他們在充當對象的同時,又是其他對象的容器的情況。在編寫時我們常常會造成:客戶代碼過多地依賴于對象容器復雜的內部實現,對象容器內部實現結構(而非抽象接口)的變化將引起客戶代碼的頻繁變化,帶來了代碼的維護性、擴展性的弊端。

                   GoF《設計模式》中說到:將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite模式使得客戶對單個對象和組合對象的使用具有一致性。

                   Composite組合模式結構如下:

             


                   說道這,我覺得有一個編程中常見的場景,就是對于樹的實現,很符合這個模式。下面我就用這個例子作一下。

                   首先,我們先分析對于一棵樹所包含的部分,樹干、樹枝、樹葉,其中樹干可以看成一個樹枝(就是粗了點)。那么我們就應該有兩種類實現Leaf(樹葉)和Limb(樹枝)。對于葉子節點和枝節點的不同在于枝節點有子樹,而葉子節點沒有子樹。為了使單個對象和組合對象的使用具有一致性,我可以將葉子節點想象成沒有子樹的枝節點。這樣我就可以得到一個抽象類,代碼如下:

                   public abstract class AbstractClass

                {

                    public string name;

                    public ArrayList list;

                    public abstract void Add(AbstractClass item);       //增加一個子節點

                    public abstract void Remove(AbstractClass item);    //去掉一個子節點

                    public abstract string Print();                     //打印當前節點

                }

                   然后,我在對葉子節點和枝節點作不同的實現:

                   枝節點:

                   public class Limb:AbstractClass

                {

                    public Limb()

                    {

                        list = new ArrayList();

                    }

             

                    public override void Add(AbstractClass item)

                    {

                        list.Add(item);

                    }

             

                    public override void Remove(AbstractClass item)

                    {

                        if(list.Contains(item))

                            list.Remove(item);

                    }

                    public override string Print()

                    {

                        Console.Write(name + "\n");

                        if(list.Count != 0)

                        {

                            for(int i = 0;i<list.Count;i++)

                            {

                                Console.Write("(Parent is " + name + ")");

                                ((AbstractClass)list[i]).Print();

                            }

                        }

                        return name;

                    }

             

                }

                葉子節點:

                public class Leaf:AbstractClass

                {

                    public Leaf()

                    {

                        list = null;

                    }

             

                    public override void Add(AbstractClass item)

                    {

             

                    }

                    public override void Remove(AbstractClass item)

                    {

                       

                    }

                    public override string Print()

                    {

                        Console.Write(name + ",");

                        return this.name;

                    }

                }

                對于葉子節點來說,不需要子節點,當然也就不需要添加和刪除子節點的方法。

                好,接下來,我們可以在客戶程序中組建一棵樹,來測試一下:

                    static void Main(string[] args)

                    {

                        AbstractClass Tree = new Limb();

                        GetTree(Tree);

                        PrintTree(Tree);

                        Console.Read();

                    }

             

                    public static void GetTree(AbstractClass Tree)

                    {

                        Tree.name = "1";

                        AbstractClass leaf2 = new Leaf();

                        leaf2.name = "2";

                        Tree.Add(leaf2);

                        AbstractClass limb3 = new Limb();

                        limb3.name = "3";

                        Tree.Add(limb3);

                        AbstractClass leaf4 = new Leaf();

                        leaf4.name = "4";

                        limb3.Add(leaf4);

                        AbstractClass leaf5 = new Leaf();

                        leaf5.name = "5";

                        limb3.Add(leaf5);

                    }

             

                    public static void PrintTree(AbstractClass Tree)

                    {

                        Tree.Print();

                    }

                輸出結果如下:

            1

            (Parent is 1)2,(Parent is 1)3

            (Parent is 3)4,(Parent is 3)5,

            在組織這個樹時,的確能感覺到GoF《設計模式》中的那句話:單個對象和組合對象的使用具有一致性。當然也的確感覺到一點矛盾:對于葉子節點來說,不需要ArrayList和Add()Remove()應該不繼承才對,當然如果在代碼執行性能可以達到要求的情況下,簡化一下編碼實現復雜度也是挺好的一件事。

            最后在來說說Composite組合模式的幾個要點:

                   1、Composite模式采用樹形結構來實現普遍存在的對象容器,從而將“一對多”的關系轉化為“一對一”的關系,使得客戶代碼可以一致的處理對象和對象容器,無需關心處理的是單個對象,還是組合的對象容器。

            2、將“客戶代碼與復雜的對象容器結構”解耦是Composite模式的核心思想,解耦之后,客戶代碼將與純粹的對象接口——而非對象容器的復雜內部實現結構——發生依賴關系,從而更能“應對變化”。

            3、Composite模式中,是將“Add和Remove的和對象容器相關的方法”定義在“表示抽象對象的Component類”中,還是將其定義在“表示對象容器的Composite類”中,是一個關乎“透明性”和“安全性”的兩難問題,需要仔細權衡結構,這又是必須付出的代價。

            4、Composite模式在具體實現中,可以讓父對象中的字對象反向追溯:如果父對象有頻繁的遍歷需求,可使用緩存技巧來改善效率

            posted on 2010-04-13 17:38 大龍 閱讀(203) 評論(0)  編輯 收藏 引用

            久久精品亚洲精品国产色婷| 青青国产成人久久91网| 久久精品桃花综合| 久久人与动人物a级毛片| 久久久噜噜噜久久熟女AA片| 国产福利电影一区二区三区久久老子无码午夜伦不| 国产精品久久成人影院| 青春久久| 99热成人精品热久久669| 久久精品免费大片国产大片| 久久久久亚洲AV成人片| 色狠狠久久综合网| 日韩亚洲欧美久久久www综合网 | 午夜天堂精品久久久久| 国产精品内射久久久久欢欢 | 久久丫精品国产亚洲av不卡| 伊人久久大香线蕉精品| 亚洲综合伊人久久大杳蕉| 亚洲?V乱码久久精品蜜桃| 国产欧美一区二区久久| 亚洲αv久久久噜噜噜噜噜| 精品久久久久久无码人妻蜜桃| 国产午夜福利精品久久2021| 中文精品久久久久人妻不卡| 久久久久亚洲精品中文字幕| 国产99久久久久久免费看| 久久久久久亚洲精品成人| 久久综合给合久久狠狠狠97色| 亚洲国产日韩欧美久久| 狠狠色综合网站久久久久久久| 国产一久久香蕉国产线看观看| 性欧美大战久久久久久久久| 97精品依人久久久大香线蕉97| 久久中文字幕人妻熟av女| 中文字幕精品无码久久久久久3D日动漫| 亚洲精品高清国产一久久| 久久精品视频免费| 国内精品伊人久久久久网站| 国产精品日韩深夜福利久久| 欧美日韩精品久久久免费观看| 亚洲精品国产综合久久一线|