Head First設(shè)計(jì)模式---裝飾者模式

定義

動(dòng)態(tài)地將責(zé)任附加到對象上。想要擴(kuò)展功能,裝飾者提供有別于繼承的另一種選擇。

例子

現(xiàn)在有一家咖啡店,需要設(shè)計(jì)一個(gè)咖啡的訂單系統(tǒng)。在最初咖啡種類較少的時(shí)候,設(shè)計(jì)了一個(gè)beverage的父類,所有的咖啡都是繼承自beverage的子類:


最初的設(shè)計(jì)

這個(gè)設(shè)計(jì)采用繼承的方式實(shí)現(xiàn)不同咖啡子類,現(xiàn)在需求有了變化,在購買咖啡的時(shí)候,可以在里面加入各種調(diào)料,比如牛奶,豆?jié){,摩卡等,這些調(diào)料也是有各自的價(jià)格。如何處理這個(gè)需求,并應(yīng)對可能的變化?

分析

我們可能有以下思路:

1.在現(xiàn)有設(shè)計(jì)下,增加新的子類。如豆?jié){濃縮咖啡,牛奶濃縮咖啡,豆?jié){深培咖啡等。
分析:這種方式本質(zhì)是窮舉法,只是理論可行而已。看起來是對咖啡 + 調(diào)料的排列組合,一一列舉出來作為一個(gè)子類。事實(shí)上,用戶完全可能需要不止一種的調(diào)料,保持這個(gè)設(shè)計(jì)將是災(zāi)難一樣。
2.上面思路不可行的原因在于,我們不知道可能會(huì)有多少組合以及按照什么樣的順序去組合。這里我們需要想明白一件事,即加了調(diào)料的飲料依然是飲料,繼續(xù)加調(diào)料還是飲料。這個(gè)事實(shí)給我們的啟發(fā)就是,我們可以設(shè)計(jì)出一個(gè)組合的對象,它組合了飲料對象和調(diào)料對象。使用起來大概是這樣的:

Beverage A = new Beverage(some beverage,  milk);
A = new Beverage(A, soy);
A = new Beverage(A, suger);
...

3.上述組合對象的思想是沒問題的,只是實(shí)現(xiàn)起來有些問題。在上面的偽代碼可以看出, 設(shè)計(jì)的飲料對象需要知道所有的飲料類(咖啡,奶茶等)和所有的調(diào)料類(豆?jié){,牛奶,摩卡等)。這個(gè)問題可以用繼承或接口實(shí)現(xiàn),組合對象里包含兩個(gè)對象,分別繼承于(或?qū)崿F(xiàn)接口)飲料類和調(diào)料類
4.繼續(xù)優(yōu)化,從實(shí)際意義看,調(diào)料類是依賴于飲料的,即飲料是調(diào)料的必要不充分條件,所以沒必要設(shè)計(jì)一系列的調(diào)料對象,調(diào)料只是裝飾飲料用的。每一種調(diào)料是一種裝飾者,需要飲料來初始化,而這個(gè)裝飾器繼承自飲料類(或者實(shí)現(xiàn)飲料接口)。類圖如下:


裝飾者模式.png

裝飾者模式的關(guān)鍵在于,裝飾者和被裝飾者有著相同的超類型,這里用到繼承或者接口的手段目的都是為了做類型匹配,另外,裝飾者可以再所委托被裝飾者的行為之前或之后,加上自己的行為,以達(dá)到特定的目的,典型的例子就是java中的io類,裝飾者模式利用了組合對象來實(shí)現(xiàn)擴(kuò)展功能。

總結(jié)

  • 繼承屬于擴(kuò)展形式之一,但不見得是達(dá)到彈性設(shè)計(jì)的最佳方式
  • 在我們的設(shè)計(jì)中,應(yīng)該允許行為可以被擴(kuò)展,而無須修改現(xiàn)有的代碼
  • 組合和委托可用于在運(yùn)行時(shí)動(dòng)態(tài)地加上新行為
  • 除了繼承,裝飾者模式也可以讓我們擴(kuò)展行為
  • 裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件
  • 裝飾者類反映出被裝飾的組件類型(具有相同的類型)
  • 可以使用無數(shù)個(gè)裝飾者包裝一個(gè)組件
  • 裝飾者會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)很多小對象,過度使用,會(huì)讓程序變得復(fù)雜

代碼

https://github.com/wszxy/DesignPattern

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工作總讓我感覺著失落.到底是看不到將來,還是在激流中不能涌現(xiàn)。這也許就是一種寂寞吧!
    隕石的脆弱閱讀 71評(píng)論 0 0
  • 2G在線的話應(yīng)該是根本不在線吧,自從星期一晚上十點(diǎn)過開始就一直是2G在線,昨天突然發(fā)現(xiàn)他居然開通qq空間了(之前一...
    許千里閱讀 427評(píng)論 0 0
  • 你就是想得太多,做得太少,才會(huì)一事無成 01 昨天和朋友聊天。我說,我在想現(xiàn)在這份工作,要不要繼續(xù)呢?朋友問我“那...
    蘆笙夕陌閱讀 1,030評(píng)論 0 1
  • 早上被老板叫到辦公室,談到公司在中國的辦事處。辦事處總共就三個(gè)人,一個(gè)經(jīng)理,兩個(gè)屬下。老板不是很滿意這個(gè)經(jīng)理,認(rèn)為...
    伊娃和阿娜閱讀 184評(píng)論 0 2

友情鏈接更多精彩內(nèi)容