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

C#面向?qū)ο笤O(shè)計(jì)模式縱橫談:Decorator 裝飾模式

  子類復(fù)子類,子類何其多

  假如我們需要為游戲中開發(fā)一種坦克,除了各種不同的型號(hào)的坦克外,我們還希望在不同場(chǎng)合中為其增加以下一種或多種功能:比如紅外線夜視功能,比如水陸兩棲功能,比如衛(wèi)星定位功能等等。

image

  如果再添加一種功能D,那么需要增加的T50子類的數(shù)量可想而知,而這只是T50這個(gè)類型,如果還有其他T70等類型,那么需要新添加的子類將不可計(jì)數(shù)。

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

  上述描述的問(wèn)題根源在于我們“過(guò)度地使用了繼承來(lái)擴(kuò)展對(duì)象的功能”,由于繼承為類型引入的靜態(tài)特質(zhì)(所謂靜態(tài)特質(zhì),就是說(shuō)如果想要某種功能,我們必須在編譯的時(shí)候就要定義這個(gè)類,這也是強(qiáng)類型語(yǔ)言的特點(diǎn)。靜態(tài),就是指在編譯的時(shí)候要確定的東西;動(dòng)態(tài),是指運(yùn)行時(shí)確定的東西),使得這種擴(kuò)展方式缺乏靈活性;并且隨著子類的增多(擴(kuò)展功能的增多),各種子類的組合(擴(kuò)展功能的組合)會(huì)導(dǎo)致更多子類的膨脹(多繼承)。

  如何使“對(duì)象功能的擴(kuò)展”能夠根據(jù)需要來(lái)動(dòng)態(tài)(即運(yùn)行時(shí))地實(shí)現(xiàn)?同時(shí)避免“擴(kuò)展功能的增多”帶來(lái)的子類膨脹問(wèn)題?從而使得任何“功能擴(kuò)展變化”所導(dǎo)致的影響降為最低?

  意圖(Intent)

  動(dòng)態(tài)地給一個(gè)對(duì)象增加一些額外的職責(zé)。就增加功能而言,Decorator模式比生成子類更為靈活。

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

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

  以前面的例子為例

image

 ?。m正:Tank應(yīng)該也是抽象類)

image

image

  這里用到了C#對(duì)于接口的顯示實(shí)現(xiàn),它在繼承的類里面是個(gè)私有的方法,但是在接口中又是公有的。下面是Decorator模式的實(shí)現(xiàn):

image

  這里Decorator類雖然繼承自Tank,但它實(shí)際上應(yīng)該是接口繼承,而不是類繼承。

image

 ?。m正:DecoratorA還應(yīng)該寫自己的構(gòu)造器,因?yàn)闃?gòu)造器不繼承)當(dāng)然,如果不需要對(duì)Shot方法或者Run方法進(jìn)行擴(kuò)展,可以不override它。

  Decorator的結(jié)構(gòu)如下

image

  客戶代碼

image

  可以看到,在Decorator的構(gòu)造器中,我們除了傳入Tank外,同樣可以傳入Decorator自己作為構(gòu)造器,這樣裝飾的功能就能夠進(jìn)行疊加。這也是為什么我們讓Decorator抽象類繼承自Tank抽象類的原因。因此,如果現(xiàn)在需要加一個(gè)功能,我們只需要添加一個(gè)功能的裝飾子類就可以了,不需要添加其它的子類。它好就好在擁有運(yùn)行時(shí)的靈活性,可以在需要用時(shí)隨意組合功能,而不需要靜態(tài)地把各種功能組合寫死在代碼中。

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

image

  Component對(duì)應(yīng)于Tank抽象類或接口;ConcreteComponent是Tank的具體實(shí)體類,對(duì)應(yīng)于T50、T75、T90。

  我們需要注意的是Decorator和Component的關(guān)系,首先是繼承關(guān)系(Is-A關(guān)系,這個(gè)Is-A關(guān)系其實(shí)是接口繼承,而不是類繼承),然后是Decorator里有一個(gè)Component的關(guān)系(Has-A關(guān)系)。擁有這兩重關(guān)系的優(yōu)勢(shì)就是能夠組合起來(lái),讓它可以不斷地?cái)U(kuò)展,把一個(gè)個(gè)裝飾串起來(lái)。

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

  通過(guò)采用組合、而非繼承的手法,Decorator模式實(shí)現(xiàn)了在運(yùn)行時(shí)(就是在客戶代碼Main函數(shù)里寫的代碼)動(dòng)態(tài)地?cái)U(kuò)展對(duì)象功能的能力,而且可以根據(jù)需要擴(kuò)展多個(gè)功能。避免了單獨(dú)使用繼承帶來(lái)的“靈活性差”和“多子類衍生問(wèn)題”。Component類在Decorator模式中充當(dāng)抽象接口的角色,不應(yīng)該去實(shí)現(xiàn)具體的行為。而且Decorator類對(duì)于Component類應(yīng)該透明——換言之Component類無(wú)需知道Decorator類,Decorator類是從外部來(lái)擴(kuò)展Component類的功能。Decorator類在接口上表現(xiàn)為Is-A:Component的繼承關(guān)系,即Decorator類繼承了Component類所具有的接口。但在實(shí)現(xiàn)上有表現(xiàn)為Has-A:Component的組合關(guān)系,即Decorator類又使用了另外一個(gè)Component類。我們可以使用一個(gè)或者多個(gè)Decorator對(duì)象來(lái)“裝飾”一個(gè)Component對(duì)象,且裝飾后的對(duì)象仍然是一個(gè)Component對(duì)象。

  Decorator模式并非解決“多子類衍生的多繼承”問(wèn)題,Decorator模式,應(yīng)用的要點(diǎn)在于解決“主體類在多個(gè)方向上的擴(kuò)展功能”——是為“裝飾”的含義。

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

image

  Stream是一個(gè)抽象接口,它在System.IO里面,它其實(shí)就是Component。FileStream、NETworkStream、MemoryStream都是實(shí)體類ConcreteComponent。右邊的BufferedStream、CryptoStream是裝飾對(duì)象,它們都是繼承了Stream接口的。

image

image

  BufferedStream

image

  BufferedStream繼承自Stream,又含有Stream作為屬性。有一點(diǎn)不同的是,BufferedStream這個(gè)具體的裝飾類沒有抽象類,直接繼承自抽象主體Stream接口,它讓Decorator抽象類退化了,但這點(diǎn)不同并不影響Decorator模式的本質(zhì)。

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

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

主站蜘蛛池模板: 爆操日本美女 | 久久久免费观成人影院 | 噼里啪啦免费观看视频大全 | 亚洲视频在线观看地址 | 午夜福利理论片高清在线 | 欧美一区二区三区不卡免费 | 精品国产成人a区在线观看 精品国产成人AV在线看 | 芭乐视频网页版在线观看 | 老熟人老女人国产老太 | 国产网红主播精品福利大秀专区 | 色尼玛亚洲综合 | 国产69精品久久久久乱码免费 | 交换娇妻呻吟声不停中文字幕 | 国产在线一区二区AV视频 | 成人精品视频99在线观看免费 | 久久偷拍国2017 | 亚洲一卡二卡三卡四卡2021麻豆 | 婚后被调教当众高潮H喷水 回复术士勇者免费观看全集 | 中文字幕专区高清在线观看 | AV天堂AV亚洲啪啪久久无码 | 美女张开腿露出尿口扒开来摸动漫 | 四虎国产精品永久免费入口 | 亚洲精品影院久久久久久 | yy8090理论三级在线看 | 国产精品永久在线 | 亚洲精品在线播放视频 | 乳巨揉みま痴汉电车中文字幕动漫 | 国产精品99久久免费黑人人妻 | 国产高清亚洲日韩字幕一区 | 做暖暖视频在线看片免费 | 精品国产露脸久久AV麻豆 | 棉袜足j吐奶视频 | 欧美另类jizzhd| 亚洲国产成人久久精品影视 | 米奇在线8888在线精品视频 | 日韩精品无码免费专区 | 久久伦理影院 | 黄色免费在线网址 | 亚洲成人精品 | 国产一区精选播放022 | 99pao成人国产永久免费视频 |