裝飾模式(Decorator)

動態(tài)地給一個對象增加一些額外的職責(zé)综膀,就增加對象功能來說挪挤,裝飾模式比生成子類實現(xiàn)更為靈活洞拨。

類型

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

簡介

裝飾模式是一種用于替代繼承的技術(shù),它通過一種無須定義子類的方式來給對象動態(tài)增加職責(zé)讼积,使用對象之間的關(guān)聯(lián)關(guān)系取代類之間的繼承關(guān)系哨苛。

參與者

在裝飾模式中,為了讓系統(tǒng)具有更好的靈活性和可擴展性币砂,我們通常會定義一個抽象裝飾類建峭,而將具體的裝飾類作為它的子類。

  • Component(抽象構(gòu)件):它是具體構(gòu)件和抽象裝飾類的共同父類决摧,聲明了在具體構(gòu)件中實現(xiàn)的業(yè)務(wù)方法亿蒸,它的引入可以使客戶端以一致的方式處理未被裝飾的對象以及裝飾之后的對象,實現(xiàn)客戶端的透明操作掌桩。
  • ConcreteComponent(具體構(gòu)件):它是抽象構(gòu)件類的子類边锁,用于定義具體的構(gòu)件對象,實現(xiàn)了在抽象構(gòu)件中聲明的方法波岛,裝飾器可以給它增加額外的職責(zé)(方法)茅坛。
  • Decorator(抽象裝飾類):它也是抽象構(gòu)件類的子類,用于給具體構(gòu)件增加職責(zé)则拷,但是具體職責(zé)在其子類中實現(xiàn)贡蓖。它維護(hù)一個指向抽象構(gòu)件對象的引用,通過該引用可以調(diào)用裝飾之前構(gòu)件對象的方法煌茬,并通過其子類擴展該方法斥铺,以達(dá)到裝飾的目的。
  • ConcreteDecorator(具體裝飾類):它是抽象裝飾類的子類坛善,負(fù)責(zé)向構(gòu)件添加新的職責(zé)晾蜘。每一個具體裝飾類都定義了一些新的行為,它可以調(diào)用在抽象裝飾類中定義的方法眠屎,并可以增加新的方法用以擴充對象的行為剔交。

用法

代碼助記

客戶端并不會覺得對象在裝飾前和裝飾后有什么不同,對客戶端透明改衩。

  • 抽象裝飾類和具體構(gòu)件類繼承于同一父類(抽象構(gòu)件)岖常;
  • 抽象裝飾類中有一指向抽象構(gòu)件對象的引用,由客戶端使用構(gòu)造器或set注入燎字;
  • 抽象裝飾類調(diào)用抽象構(gòu)件對象的原業(yè)務(wù)方法(多態(tài)到具體構(gòu)件類)腥椒;
  • 具體裝飾類復(fù)寫業(yè)務(wù)方法阿宅,調(diào)用抽象類業(yè)務(wù)方法,并擴展業(yè)務(wù)方法笼蛛;
  • 客戶端需要知道裝飾類洒放,由客戶端組裝(注入構(gòu)件對象);
一次裝飾

將具體構(gòu)件對象注入裝飾類中滨砍。

嵌套(多次)裝飾

將一個已經(jīng)裝飾過的裝飾子類對象再注入裝飾類中往湿。

兩種模式

開發(fā)過程中,具體裝飾類中有可能有新增的方法需要調(diào)用惋戏。這樣客戶端聲明對象時领追,不能統(tǒng)一使用抽象構(gòu)件類型定義,而需要將調(diào)用新增方法的地方使用具體裝飾類來聲明响逢。這種情況稱為非透明绒窑,其實是由多態(tài)中向上轉(zhuǎn)型后不能再調(diào)用子類中新增方法引入的。

透明裝飾模式(Transparent)
  • 在透明裝飾模式中舔亭,要求客戶端完全針對抽象編程些膨。
  • 要求客戶端程序不應(yīng)該將對象聲明為具體構(gòu)件類型或具體裝飾類型,而應(yīng)該全部聲明為抽象構(gòu)件類型钦铺。
  • 使用抽象構(gòu)件類型Component定義全部具體構(gòu)件對象和具體裝飾對象订雾,客戶端可以一致地使用這些對象,無須關(guān)心它們的區(qū)別矛洞。此外洼哎,還可以對一個已裝飾過的對象進(jìn)行多次裝飾,得到更為復(fù)雜沼本、功能更為強大的對象噩峦。
半透明裝飾模式(Semi-transparent)
  • 為了能夠調(diào)用到新增方法,我們不得不用具體裝飾類型來定義裝飾之后的對象擅威,而具體構(gòu)件類型還是可以使用抽象構(gòu)件類型來定義壕探;
  • 對于客戶端而言,具體構(gòu)件類型無須關(guān)心郊丛,是透明的;但是具體裝飾類型必須指定瞧筛,這是不透明的厉熟;
  • 半透明裝飾模式可以給系統(tǒng)帶來更多的靈活性,設(shè)計相對簡單较幌,使用起來也非常方便揍瑟;
  • 缺點在于不能實現(xiàn)對同一個對象的多次裝飾,而且客戶端需要有區(qū)別地對待裝飾之前的對象和裝飾之后的對象乍炉。

總結(jié)

  • 盡量保持裝飾類的接口與被裝飾類的接口相同绢片,應(yīng)該盡量使用透明裝飾模式滤馍。
  • 盡量保持具體構(gòu)件類ConcreteComponent是一個“輕”類,也就是說不要把太多的行為放在具體構(gòu)件類中底循,我們可以通過裝飾類對其進(jìn)行擴展巢株。
  • 如果只有一個具體構(gòu)件類,那么抽象裝飾類可以作為該具體構(gòu)件類的直接子類熙涤。
優(yōu)點
  • 對于擴展一個對象的功能阁苞,裝飾模式比繼承更加靈活性,不會導(dǎo)致類的個數(shù)急劇增加祠挫。
  • 可以通過一種動態(tài)的方式來擴展一個對象的功能那槽,通過配置文件可以在運行時選擇不同的具體裝飾類,從而實現(xiàn)不同的行為等舔。
  • 可以對一個對象進(jìn)行多次裝飾骚灸,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創(chuàng)造出很多不同行為的組合慌植,得到功能更為強大的對象逢唤。
  • 具體構(gòu)件類與具體裝飾類可以獨立變化,用戶可以根據(jù)需要增加新的具體構(gòu)件類和具體裝飾類涤浇,原有類庫代碼無須改變鳖藕,符合“開閉原則”。
缺點
  • 使用裝飾模式進(jìn)行系統(tǒng)設(shè)計時將產(chǎn)生很多小對象只锭,這些對象的區(qū)別在于它們之間相互連接的方式有所不同著恩,而不是它們的類或者屬性值有所不同,大量小對象的產(chǎn)生勢必會占用更多的系統(tǒng)資源蜻展,在一定程序上影響程序的性能喉誊。
  • 裝飾模式提供了一種比繼承更加靈活機動的解決方案,但同時也意味著比繼承更加易于出錯纵顾,排錯也很困難伍茄,對于多次裝飾的對象,調(diào)試時尋找錯誤可能需要逐級排查施逾,較為繁瑣敷矫。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市汉额,隨后出現(xiàn)的幾起案子曹仗,更是在濱河造成了極大的恐慌,老刑警劉巖蠕搜,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怎茫,死亡現(xiàn)場離奇詭異,居然都是意外死亡妓灌,警方通過查閱死者的電腦和手機轨蛤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門蜜宪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人祥山,你說我怎么就攤上這事圃验。” “怎么了枪蘑?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵损谦,是天一觀的道長。 經(jīng)常有香客問我岳颇,道長照捡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任话侧,我火速辦了婚禮栗精,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞻鹏。我一直安慰自己悲立,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布新博。 她就那樣靜靜地躺著薪夕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赫悄。 梳的紋絲不亂的頭發(fā)上原献,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音埂淮,去河邊找鬼姑隅。 笑死,一個胖子當(dāng)著我的面吹牛倔撞,可吹牛的內(nèi)容都是我干的讲仰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼痪蝇,長吁一口氣:“原來是場噩夢啊……” “哼鄙陡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起霹俺,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤柔吼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丙唧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡觅玻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年想际,在試婚紗的時候發(fā)現(xiàn)自己被綠了培漏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡胡本,死狀恐怖牌柄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情侧甫,我是刑警寧澤珊佣,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站披粟,受9級特大地震影響咒锻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜守屉,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一惑艇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拇泛,春花似錦滨巴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熄守,卻和暖如春蜈垮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柠横。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工窃款, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牍氛。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓晨继,卻偏偏與公主長得像,于是被迫代替她去往敵國和親搬俊。 傳聞我的和親對象是個殘疾皇子紊扬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用唉擂、多...
    MinoyJet閱讀 3,948評論 1 15
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法餐屎,類相關(guān)的語法,內(nèi)部類的語法玩祟,繼承相關(guān)的語法腹缩,異常的語法,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • 當(dāng)我們要為一個對象添加新的方法時,我們一般有兩種方式: 繼承機制 通過繼承一個現(xiàn)有類使得子類也擁有父類的方法藏鹊,然...
    堅堅老師閱讀 901評論 0 2
  • (轉(zhuǎn)載)原文地址 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述裝飾(Decorator)模式的: 裝飾模式又...
    zjk_00閱讀 635評論 0 2
  • 定義 裝飾器模式又名包裝(Wrapper)模式润讥。裝飾器模式以對客戶端透明的方式拓展對象的功能,是繼承關(guān)系的一種替代...
    步積閱讀 35,381評論 0 38