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

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            設(shè)計(jì)模式學(xué)習(xí)筆記(九)——Composite組合模式

                  Composite組合模式主要是應(yīng)對(duì)這樣的問(wèn)題:一類具有“容器特征”的對(duì)象——即他們?cè)诔洚?dāng)對(duì)象的同時(shí),又是其他對(duì)象的容器的情況。在編寫時(shí)我們常常會(huì)造成:客戶代碼過(guò)多地依賴于對(duì)象容器復(fù)雜的內(nèi)部實(shí)現(xiàn),對(duì)象容器內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)(而非抽象接口)的變化將引起客戶代碼的頻繁變化,帶來(lái)了代碼的維護(hù)性、擴(kuò)展性的弊端。

                   GoF《設(shè)計(jì)模式》中說(shuō)到:將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite模式使得客戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

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

             


                   說(shuō)道這,我覺(jué)得有一個(gè)編程中常見的場(chǎng)景,就是對(duì)于樹的實(shí)現(xiàn),很符合這個(gè)模式。下面我就用這個(gè)例子作一下。

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

                   public abstract class AbstractClass

                {

                    public string name;

                    public ArrayList list;

                    public abstract void Add(AbstractClass item);       //增加一個(gè)子節(jié)點(diǎn)

                    public abstract void Remove(AbstractClass item);    //去掉一個(gè)子節(jié)點(diǎn)

                    public abstract string Print();                     //打印當(dāng)前節(jié)點(diǎn)

                }

                   然后,我在對(duì)葉子節(jié)點(diǎn)和枝節(jié)點(diǎn)作不同的實(shí)現(xiàn):

                   枝節(jié)點(diǎn):

                   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;

                    }

             

                }

                葉子節(jié)點(diǎn):

                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;

                    }

                }

                對(duì)于葉子節(jié)點(diǎn)來(lái)說(shuō),不需要子節(jié)點(diǎn),當(dāng)然也就不需要添加和刪除子節(jié)點(diǎn)的方法。

                好,接下來(lái),我們可以在客戶程序中組建一棵樹,來(lái)測(cè)試一下:

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

                    }

                輸出結(jié)果如下:

            1

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

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

            在組織這個(gè)樹時(shí),的確能感覺(jué)到GoF《設(shè)計(jì)模式》中的那句話:?jiǎn)蝹€(gè)對(duì)象和組合對(duì)象的使用具有一致性。當(dāng)然也的確感覺(jué)到一點(diǎn)矛盾:對(duì)于葉子節(jié)點(diǎn)來(lái)說(shuō),不需要ArrayList和Add()Remove()應(yīng)該不繼承才對(duì),當(dāng)然如果在代碼執(zhí)行性能可以達(dá)到要求的情況下,簡(jiǎn)化一下編碼實(shí)現(xiàn)復(fù)雜度也是挺好的一件事。

            最后在來(lái)說(shuō)說(shuō)Composite組合模式的幾個(gè)要點(diǎn):

                   1、Composite模式采用樹形結(jié)構(gòu)來(lái)實(shí)現(xiàn)普遍存在的對(duì)象容器,從而將“一對(duì)多”的關(guān)系轉(zhuǎn)化為“一對(duì)一”的關(guān)系,使得客戶代碼可以一致的處理對(duì)象和對(duì)象容器,無(wú)需關(guān)心處理的是單個(gè)對(duì)象,還是組合的對(duì)象容器。

            2、將“客戶代碼與復(fù)雜的對(duì)象容器結(jié)構(gòu)”解耦是Composite模式的核心思想,解耦之后,客戶代碼將與純粹的對(duì)象接口——而非對(duì)象容器的復(fù)雜內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)——發(fā)生依賴關(guān)系,從而更能“應(yīng)對(duì)變化”。

            3、Composite模式中,是將“Add和Remove的和對(duì)象容器相關(guān)的方法”定義在“表示抽象對(duì)象的Component類”中,還是將其定義在“表示對(duì)象容器的Composite類”中,是一個(gè)關(guān)乎“透明性”和“安全性”的兩難問(wèn)題,需要仔細(xì)權(quán)衡結(jié)構(gòu),這又是必須付出的代價(jià)。

            4、Composite模式在具體實(shí)現(xiàn)中,可以讓父對(duì)象中的字對(duì)象反向追溯:如果父對(duì)象有頻繁的遍歷需求,可使用緩存技巧來(lái)改善效率

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


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产精品日韩欧美久久综合| 国产精品久久网| 午夜视频久久久久一区| 伊人久久大香线蕉亚洲五月天| 久久精品毛片免费观看| 精品熟女少妇aⅴ免费久久| 久久久久久精品免费免费自慰| 国产精品久久国产精麻豆99网站| 国产精品99久久精品爆乳| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 人妻久久久一区二区三区| 91精品国产高清久久久久久国产嫩草| 久久精品人妻一区二区三区| 国内精品久久久人妻中文字幕| 久久久久久噜噜精品免费直播| 香蕉久久夜色精品升级完成| 欧美成a人片免费看久久| 91精品国产高清久久久久久io | 亚洲va中文字幕无码久久| 久久影视国产亚洲| 日本免费久久久久久久网站| 日韩精品久久无码人妻中文字幕| 久久久WWW成人免费毛片| 精品九九久久国内精品| 亚洲精品乱码久久久久66| 欧美亚洲国产精品久久高清| 国产亚洲美女精品久久久| 久久精品www| 26uuu久久五月天| 久久青青草原综合伊人| 久久国产成人精品麻豆| 久久久久中文字幕| 精品免费tv久久久久久久| A狠狠久久蜜臀婷色中文网| 人妻精品久久久久中文字幕一冢本| 久久精品国产亚洲AV久| 欧美精品国产综合久久| 日韩人妻无码一区二区三区久久99 | 欧洲国产伦久久久久久久| 久久99国产综合精品免费| 久久国产精品一国产精品金尊|