天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

C#面向?qū)ο笤O(shè)計(jì)模式縱橫談:Composite 組合模式

  對(duì)象容器的問(wèn)題

  在面向?qū)ο笙到y(tǒng)中,我們常會(huì)遇到一類(lèi)具有“容器”特征的對(duì)象——即它們?cè)诔洚?dāng)對(duì)象的同時(shí),又是其他對(duì)象的容器。

image

  如果我們要對(duì)這樣的對(duì)象容器進(jìn)行處理:

image

  上面是客戶代碼,客戶代碼里面必須要知道對(duì)象的結(jié)構(gòu),有可能還要使用遞歸的方法來(lái)處理這個(gè)對(duì)象,這樣寫(xiě)耦合性就比較高。客戶代碼如果能只和IBox發(fā)生依賴(lài)就很好了,但是現(xiàn)在它還和ContainerBox和SingleBox發(fā)生了依賴(lài),這樣內(nèi)部實(shí)現(xiàn)的細(xì)節(jié)就暴露給了外界,并且和外界產(chǎn)生了依賴(lài)關(guān)系。

  動(dòng)機(jī)(Motivation)

  上述描述的問(wèn)題根源在于:客戶代碼過(guò)多地依賴(lài)于對(duì)象容器復(fù)雜的內(nèi)部實(shí)現(xiàn)結(jié)構(gòu),對(duì)象容器內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)(而非抽象接口)的變化將引起客戶代碼的頻繁變化,帶來(lái)了代碼的維護(hù)性、擴(kuò)展性等弊端。如何將“客戶代碼與復(fù)雜的對(duì)象容器結(jié)構(gòu)”解耦?讓對(duì)象容器自己來(lái)實(shí)現(xiàn)自身的復(fù)雜結(jié)構(gòu),從而使得客戶代碼就像處理簡(jiǎn)單對(duì)象一樣來(lái)處理復(fù)雜的對(duì)象容器?

  意圖(Intent)

  將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

                                              ——《設(shè)計(jì)模式》GoF

  例說(shuō)Composite應(yīng)用

  以前面的例子為例

image

image

  改進(jìn)的方案

  期望的客戶代碼:

image

  接口和SingleBox代碼都不變

image

image

  ContainerBox代碼變化

image

  這樣做ContainerBox里面的Process方法就不用判斷是否是ContainerBox還是SingleBox,因?yàn)樗鼈儓?zhí)行的方法名字都叫做Process。而且客戶代碼也只用調(diào)用box的Process方法即可。但是這里還有一個(gè)問(wèn)題,客戶代碼訪問(wèn)不了ContainerBox的Add和Remove方法,因?yàn)镮Box接口里沒(méi)有定義。

  為了解決這個(gè)問(wèn)題,我們可以選擇在IBox接口里添加兩個(gè)方法Add和Remove,然后SingleBox的Add和Remove方法什么都不做或者拋出異常。

image

  但這樣的處理方法也和理想的方法有點(diǎn)差距,因?yàn)镮Box這個(gè)類(lèi)并不符合我們類(lèi)的單一職責(zé)原則,它有SingleBox和ContainerBox二者的職責(zé),因此SingleBox對(duì)于Add和Remove也比較不好處理。但是總的來(lái)說(shuō),我們還是完成了客戶代碼的解耦工作。

  我們看看整個(gè)代碼的結(jié)構(gòu),ContainerBox里面包含了很多IBox,這些IBox有的是ContainerBox,有的也是SingleBox,因此它很像一個(gè)樹(shù)形的結(jié)構(gòu)。

  結(jié)構(gòu)(Structure)

image

  Component抽象類(lèi)或者接口對(duì)應(yīng)之前例子中的IBox,Leaf對(duì)應(yīng)SingleBox,Composite對(duì)應(yīng)ContainerBox。客戶代碼只依賴(lài)于Component抽象類(lèi)或者結(jié)構(gòu),這正是我們期望的目的。

  Composite模式的幾個(gè)要點(diǎn)

  Composite模式采用樹(shù)形結(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ì)象容器。

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

  Composite模式中,是將“Add和Remove等和對(duì)象容器相關(guān)的方法”定義在“表示抽象對(duì)象的Component類(lèi)”中,還是將其定義在“表示對(duì)象容器的Composite類(lèi)”中,是一個(gè)關(guān)乎“透明性”和“安全性”的兩難問(wèn)題,需要仔細(xì)權(quán)衡。這里有可能違背面向?qū)ο蟮?ldquo;單一職責(zé)原則”,但是對(duì)于這種特殊結(jié)構(gòu),這又是必須付出的代價(jià)。ASP.NET控件的實(shí)現(xiàn)在這方面為我們提供了一個(gè)很好的示范。

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

  .NET框架中的Composite應(yīng)用

  ASP.NET中的Panel對(duì)象就是一個(gè)Composite對(duì)象,而B(niǎo)utton對(duì)象就是Leaf對(duì)象。Button和Panel都繼承自System.Web.UI.Control類(lèi)。

image

  它實(shí)際上是在Panel里面加了一個(gè)Controls屬性,然后Controls屬性是一個(gè)集合屬性,它有Add和Remove方法。這樣我們的IBox也可以改為:

image

  在ASP.NET中就是這樣,每一個(gè)控件都有Controls屬性,也就是說(shuō)每個(gè)控件都是一種容器控件(除了LiteralControl)。這種方式把我們對(duì)安全性的擔(dān)憂,統(tǒng)統(tǒng)放到容器(即ASP.NET中的Controls,以及例子中的Boxes)中去處理。

it知識(shí)庫(kù)C#面向?qū)ο笤O(shè)計(jì)模式縱橫談:Composite 組合模式,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 2021国产在线视频 | 香蕉动漫库 | 美女丝袜夹b | 成人影院久久久久久影院 | 大胸女晃奶动态图 | 色狠狠一区 | 杨幂被视频在线观看 | 99RE8国产这里只有精品 | 欧美手机在线播放 | 九九热视频 这里有精品 | 少妇大荫蒂毛多毛大 | 一本色道久久综合一区 | 一本久道久久综合狠狠躁AV | 麻豆国产成人AV在线 | 91精品国产高清久久久久久 | 日本xxxxx按摩19 | 亚洲AV久久久久久久无码 | 欧美性动漫3d在线观看完整版 | 免费无码一区二区三区蜜桃大 | 偷上邻居熟睡少妇 | 成人在线免费观看 | 久草热8精品视频在线观看 久草青青在线 | 狠狠婷婷综合久久久久久 | 亚洲色欲国产免费视频 | 一线高清视频在线播放 | 人人澡人人擦人人免费 | 无套内射在线观看THEPORN | 久久AV喷吹AV高潮欧美 | 美女网站免费看 | 国产白色视频在线观看w | 欲香欲色天天影视大全 | 亚洲免费每日在线观看 | 九九热在线视频观看这里只有精品 | 伦理在线影院伦理电影 | 国产亚洲精品黑人粗大精选 | 久久精品一本到99热 | 亚洲精品国产AV成人毛片 | 国产精品久人妻精品 | 精品免费久久久久久成人影院 | 在线不卡日本v二区 | 国产不卡一卡2卡三卡4卡网站 |