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

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

  對象容器的問題

  在面向?qū)ο笙到y(tǒng)中,我們常會遇到一類具有“容器”特征的對象——即它們在充當(dāng)對象的同時,又是其他對象的容器。

image

  如果我們要對這樣的對象容器進行處理:

image

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

  動機(Motivation)

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

  意圖(Intent)

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

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

  例說Composite應(yīng)用

  以前面的例子為例

image

image

  改進的方案

  期望的客戶代碼:

image

  接口和SingleBox代碼都不變

image

image

  ContainerBox代碼變化

image

  這樣做ContainerBox里面的Process方法就不用判斷是否是ContainerBox還是SingleBox,因為它們執(zhí)行的方法名字都叫做Process。而且客戶代碼也只用調(diào)用box的Process方法即可。但是這里還有一個問題,客戶代碼訪問不了ContainerBox的Add和Remove方法,因為IBox接口里沒有定義。

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

image

  但這樣的處理方法也和理想的方法有點差距,因為IBox這個類并不符合我們類的單一職責(zé)原則,它有SingleBox和ContainerBox二者的職責(zé),因此SingleBox對于Add和Remove也比較不好處理。但是總的來說,我們還是完成了客戶代碼的解耦工作。

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

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

image

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

  Composite模式的幾個要點

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

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

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

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

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

  ASP.NET中的Panel對象就是一個Composite對象,而Button對象就是Leaf對象。Button和Panel都繼承自System.Web.UI.Control類。

image

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

image

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

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

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

主站蜘蛛池模板: 亚洲精品AV无码永久无码 | 狠狠色狠狠色88综合日日91 | 久久久精品久久 | 一道本av免费不卡播放 | 丝袜美女自摸 | 色噜噜噜亚洲男人的天堂 | 抽插内射高潮呻吟V杜V | 无码国产成人午夜在线观看不卡 | 国产成人a视频在线观看 | 欧美国产精品久久久乱码 | 精品无码国产自产在线观看 | 色婷婷五月综合中文字幕 | 性西欧俄罗斯极品 | 欧美日韩视频高清一区 | 超碰免费视频caopoom9 | 日本超A大片在线观看 | 久久国产视频网 | 99久久综合精品免费 | Y8848高清私人影院软件优势 | 欧美97色伦综合网 | 日韩中文字幕亚洲无线码 | 少妇的肉体AA片免费 | 亚洲天堂一区二区三区 | 洗濯屋H纯肉动漫在线观看 羲义嫁密着中出交尾gvg794 | 午夜伦伦电影理论片费看 | 日韩亚洲视频一区二区三区 | 久久这里只有热精品18 | 亚洲欧洲精品成人久久曰影片 | 精品无码久久久久久久久 | 真实国产乱子伦精品一区二区三区 | 性色少妇AV蜜臀人妻无码 | 伊人精品在线 | 共妻肉多荤文高h一女n男 | 丹麦1o一19sex性hdhd | 亚洲欧美日本中文子不卡 | 97国产在线播放 | 国产h视频在线观看免费 | 神马影院在线eecss伦理片 | 女人一级毛片免费观看 | 色悠久久久久综合欧美99 | 久久综合网久久综合 |