> For the complete documentation index, see [llms.txt](https://jen-hsuan-hsieh.gitbook.io/design-pattern/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jen-hsuan-hsieh.gitbook.io/design-pattern/chapter5-zhuang-shi-zhe-mo-shi-decorater-pattern.md).

# Chapter5: 裝飾者模式 (Decorater Pattern)

## This section contain the following items:

1.Decorator Pattern

## 1.Decorator Pattern

* 裝飾者模式要解決的問題:
  * 1.當主要物件搭配上各種裝飾品(屬性, 配件, 配料等)後會形成各種新物件, 並且與本來的物件有本質的差異, 若逐一實踐每個組合則會有**重複實踐**以及**後續維護**等問題存在
    * 例如飲料店有各種飲料, 每種飲料又可以添加各種配料, 其排列組合相當多
  * 2.使用**繼承**雖然可以解決**類別爆炸**的問題, 但一旦有新的組合需要被實踐時就必須修改這個物件, 但這樣就違反了**開放封閉原則**, 因此並不是一個好作法(以下圖片引用自"深入淺出設計模式")

![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0LpwVk_EFIpHTeBu%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-04%20%E4%B8%8A%E5%8D%888.10.23.png?generation=1586302919420051\&alt=media)

* 因此要如何解決以上問題呢? 就是利用裝飾者模式

  * 元件 + 裝飾者 = 裝飾者模式&#x20;

  ![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0LpyBt5tuaedrrni%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-04%20%E4%B8%8A%E5%8D%888.30.31.png?generation=1586302919277625\&alt=media)

  * 舉例來說, 客人希望一個darkroast咖啡, 或是darkroast的mocha咖啡, 又或是darkroast的mocha咖啡加上whip, 用裝飾者模式的做法就是將這三者拆開來, 因為其他種類的咖啡也可能會用到mocha或是whip(以下圖片引用自"深入淺出設計模式")

  ![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0Lq-OLeJsaw9ZIoF%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-04%20%E4%B8%8A%E5%8D%888.38.03.png?generation=1586302919380626\&alt=media)
* 角色(以下圖片引用自"深入淺出設計模式")
  * 裝飾者 (Decorator): 須實作的功能依需求而定
  * 元件 (Component): 須實作的功能依需求而定

![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0Lq1v9D45Lz79nGP%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-04%20%E4%B8%8A%E5%8D%888.42.42.png?generation=1586302919371007\&alt=media)

* 更仔細點觀察, **裝飾者**與**元件**必須有相同的超類別, 也就是說**必須實踐相同的Interface**(以下圖片引用用自"深入淺出設計模式")
* 實踐相同的Interface是為了要有正確的型態, 而不是繼承他的行為. 行為是來自裝飾者與元件, 或和其他裝飾者間的合成關係

  ![](https://1330730840-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G8D7wlLIQ3stULq%2F-M4M0IKc4rWLYnAL_jem%2F-M4M0Lq3Ty743e8ABSyi%2F%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202017-05-04%20%E4%B8%8A%E5%8D%888.52.23.png?generation=1586302919369655\&alt=media)
* 觀察者模式的優點
  * 1.如同[**策略模式**](https://jenhsuan.gitbooks.io/design-pattern/content/chapter3_ce_lve_mo_shi__strategy_pattern.html)的優點, 藉由動態合成物件, 可以改寫新的程式碼擴充既有的系統而無需改變既有系統的程式碼
  * 2.**裝飾者模式**動態地將責任加諸於物件上. 若要擴充功能, 裝飾者提供了比繼承更有彈性的選擇
