第三個模式:裝飾者模式架構
3.1 模式引入框架
辛巴克咖啡,購買咖啡時,也能夠要求在其中加入各類調料,例如:蒸奶(Steamed milk)、豆漿(soy)、摩卡(Mocha)或者覆蓋奶泡。星巴克會根據所加入的調料收取不一樣的費用。因此訂單系統必須考慮到這些調料部分。 設計
3.2 解決方案1:對象
採用繼承來實現方案: blog
這種方案的特色: 繼承
1.一旦出現新調料,咱們將須要加上新的方法,並改變超類中的cost()方法; 開發
2.之後開發新的飲料,對這些新飲料而言,某些調料可能並不合適,可是在這個設計方式中,Tea(茶)子類依然繼承那些不合適的方法 get
3.萬一客戶須要雙倍摩卡,怎麼辦?? it
設計原則:類應該對擴展開放,對修改關閉 擴展
如上所示咱們已經知道繼承沒法徹底解決咱們想要的問題,容易出現:類數量爆炸、設計死板、以及基類加入的新功能並不適用全部的子類。
3.2 解決方案2:
咱們考慮引入新的方法:咱們要以飲料爲主體,而後在運行時以調料來「裝飾」飲料。比方說,若是顧客想要摩卡和奶泡深賠咖啡,那麼,要作的是:
咱們由此能夠知道:
由此引入裝飾者模型:
裝飾者模型:動態地將責任附加到對象上,若要擴張功能,裝飾者提供了比繼承更有彈性的替代方案。
以下圖是裝飾者模型的類圖:
下面是星巴克的框架:
裝飾者模型的重點在於:裝飾者和被裝飾者必須是一致的類型,也就是擁有共同的超類,這是至關關鍵的地方。在這裏咱們利用繼承達到了「類型匹配」,而不是利用繼承得到「行爲」。
具體的實現能夠見源代碼,o(∩_∩)o 。
下面是片斷:
3.4裝飾者模型的應用:JAVA I/O
下圖是JAVA I/O的類圖架構: