分類

結構型模式。

這個模式在解決什麼

裝飾模式要處理的是「功能需要靈活疊加,但不想用大量子類去擴展」的問題。當功能組合一多,單靠繼承通常很快就會出現子類爆炸。

核心做法

它會用一個和原始對象共享同一抽象接口的裝飾者,把原始對象包起來,然後在包裝層追加新職責。

這代表:

  • 功能可以在運行時疊加
  • 對象的行為不必在編譯期就被繼承結構寫死

什麼時候適合用

當你發現某個基類底下開始出現大量組合式子類時,就該警覺是否適合用裝飾模式。

例子

咖啡是一個常見例子。

如果基類是咖啡,然後你有:

  • 黑咖啡
  • 牛奶咖啡
  • 酸味咖啡

接著又需要:

  • 酸味牛奶咖啡
  • 雙倍牛奶黑咖啡
  • 加糖酸味咖啡

那只靠繼承很快就會失控。裝飾模式的想法,是把「牛奶」「酸味」「加糖」這些額外職責拆成可疊加的裝飾者,而不是每種組合都做一個子類。

類圖

使用限制

裝飾模式的代價之一,是外部通常只以抽象類型來引用最外層對象。因此,如果客戶端想做某些只屬於具體類型的特殊操作,就可能不方便,因為它看到的只是統一接口。

這一篇先記住的重點

  • 裝飾模式適合替代過度繼承帶來的子類爆炸
  • 它的關鍵是「包裝並追加職責」
  • 功能的組合可以改成運行時決定,而不是編譯時固定

參考書目

《Head First Design Patterns》Eric Freeman, Elisabeth Robson, Kathy Sierra, Bert Bates