介紹php
裝飾者模式動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。設計模式
思惟導圖框架
有這樣一個項目,作一個餐廳訂餐系統。起初的代碼結構是這樣的。前面有不少Beverage的繼承類,如今遇到的問題是牛奶的價錢上漲了,那麼全部相關的類,咱們都要進行調整,好比Milk,SugarAndMilk類,這種類還有不少,咱們須要逐個去修改類中的方法——開發人員每次都作這種事情,要瘋了!因此咱們要改變現有的結構。如下的圖都是簡圖,實際的圖,可沒有這麼簡單。this
設計問題:spa
1》類數量爆炸,有不少類,難以維護;設計
2》整個設計呆板;code
3》基類加入的新功能沒法使用於子類;對象
複用類方法的方式不少,好比繼承,組合,委託。爲何總是習慣用繼承呢?我看Zend Framework也有這種習慣!每次找對應方法,一直往上翻。——題外話!!!!blog
後來通過小組研究決定,咱們決定把基礎類抽出來,好比,咱們把咖啡作成一個單獨的類,其餘的咖啡,好比牛奶咖啡,甜味咖啡,咱們只對材料單獨包裝成一個類。繼承
通過改良的設計:
詳解
1》對於飲品,咱們直接繼承Beverage類,直接把報價寫進飲品類裏面;
2》而對於一些須要添加調味品的特殊飲品,咱們作累加操做。好比,我想要杯奶咖啡,則 總價=咖啡價+奶價
3》這樣不一樣的飲料就很容易知道它的價格。
代碼
|
總結
1.裝飾者(Milk)和被裝飾者(Coffee)必須是同樣的類型。目的是裝飾者必須取代被裝飾者。
2.添加行爲:當裝飾者和組件組合時,就是在加入新的行爲。
題外話:
1.利用繼承設計子類行爲,是在編譯時靜態決定的,並且全部的子類都會繼承到相同的行爲。打個比方,老子想學點功夫,看你小子會太極拳,老子只須要繼承你一下 ,老子也就會太極拳了——呵呵,這時老子就變成你兒子了,看來繼承是要付出代價的。
2.組合,咱們能夠擴展對象的行爲,在運行時動態地進行擴展。利用組合咱們能夠隨時把咱們當時設計超類時沒有想到的方法加入到對象中,而不用改變現有的代碼。打個比方,老子如今沒有內力,吸功大法,把和尚,尼姑,道士的內力(行爲對象)都吸過來,那在搏鬥(運行時)中,老子能夠隨時都能使用不一樣的內力,但也不能胡亂吸內力,不然你就要走火入魔了!
3.類應該對擴展開放,對修改關閉。若是咱們每一個部分都用裝飾者模式進行設計,那麼對於整個框架來講有點浪費,並且你也加大了代碼的難度。那何時使用這種模式呢?咱們通常用於常常改變的地方。那咱們又怎麼知道哪些是常常改變的地方呢?這個就須要咱們的經驗和你對所處行業的瞭解。建議你們平時多看點例子。
4.裝飾模式爲設計注入彈性,但同時會在設計中加入大量的小類,這偶爾會致使別人不容易瞭解這種設計。
5.在使用裝飾者模式的時候,對插入的的裝飾者要特別當心。由於裝飾者模式依賴某種特定的類型(Beverage)。
6.要想很好的使用裝飾者模式,咱們還要配合使用工廠模式和生成器模式,但今天只說裝飾者模式。要想知道更多,請聽下回分解。
參考文獻:《head first 設計模式》