執行時擴充套件,遠比編譯時繼承威力大。
熟悉了裝飾的技巧,能夠在不改變任何底層**的情況下,給你的物件賦予新的職責。
星巴茲starbuzz以擴張速度快聞名,準備更新訂單系統,以適應他們的飲料**要求。
原先類的設計:
現在想購買咖啡時,可以要求在其中加入各種調料,如蒸奶(steamed milk)、豆漿(soy)、摩卡(mocha,也就是巧克力風味)或覆蓋奶泡,根據加入的調料收取不同費用,訂單系統需要考慮這些調料部分。
這樣子類通過覆蓋cost()擴充套件超類的功能,計算指定的飲料型別加入調料的**
其實還是有潛在的問題:
設計原則:類應該對擴充套件開放,對修改關閉
目標是允許類容易擴充套件,在不修改現有**的情況下,就可搭配新的行為。如能實現這樣的目標,會具有彈性可以應對改變,可以接受新的功能應對改變的需求。
對擴充套件開放,對修改關閉,如何兼顧
乍聽很矛盾,越難修改的食物,就越難擴充套件。
但有些聰明的oo技巧,如之前的觀察者模式,通過加入新的觀察者,可在任何時候擴充套件主題subject,而且不需要向主題中加入**。
如何將某件東西設計為可以擴充套件,又禁止修改
使用裝飾者模式就是很好的例子
如何讓設計的每個部分都遵循開放-關閉原則
通常辦不到也沒必要。遵循開放-關閉原則,通常會引入新的抽象層次,增加**的複雜度,需要將注意力集中在設計中最有可能改變的地方,然後應用開放-關閉原則。
如何知道哪些地方的改變最重要
涉及到經驗和對工作領域的了解程度。
利用繼承無法完全解決問題,在星巴茲遇到的問題有:類數量**、設計死板,以及基類加入的新功能並不適用於所有子類。
需要採取不一樣的做法:以飲料為主體,然後在執行時以調料來裝飾(decorate)飲料。如,如果顧客想要摩卡和奶泡深焙咖啡,要做的是:
拿乙個darkroast物件
以摩卡mocha物件裝飾它
以奶泡whip物件裝飾它
呼叫cost()方法,並依賴委託delegate將調料的**加上去
如何裝飾乙個物件,而委託又要如何與此搭配使用呢?把裝飾者物件看做「包裝者」
未完待續
todo
《Head first設計模式》學習筆記
開閉原則的意思是 對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的 實現乙個熱插拔的效果。簡言之,是為了使程式的擴充套件性好,易於維護和公升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。黎克特制代換原則是物件導向設計的基本原則之一。黎克特制代...
headfirst設計模式
花了一周多一點的時間看完了headfirst的設計模式。看完之後有一種恍然大悟的感覺,仔細想想有覺得自己好像什麼也看懂。簡單說下對這本書的一點感悟吧,headfirst的書比較通俗易懂,之前看了四人幫的設計模式,看一半就有一種痛不欲生的感覺,自己水平有限,看不懂,也就沒在勉強自己了。對於模式其實簡單...
HeadFirst 設計模式 工廠模式
定義乙個建立物件的介面,由子類決定要例項化的類。工廠方法將類例項推遲到子類。依賴倒置。第一種方式是 class pizzastore public pizza orderpizza string type class pizzafactory pizza pizza null 將pizza這個例項提...