設計模式(7) Decorator 裝飾模式

2021-07-09 19:41:19 字數 1413 閱讀 4702

裝飾模式也是一種日常編碼中經常會不自覺採用的設計模式。其核心理念是:乙個類有自己的核心功能和職責,且這個類的**相對已經固定,不希望改動維護。現在要為這個類加入一謝額外的功能,這些功能不是一定必須的,而且可能是動態新增的,根據實際要求加入某一種或幾種。但是不管加入什麼額外功能,客戶眼中始終還是在操作這個核心功能類。這個時候,我們的處理方式就是,為每種動態的功能,單獨的提供乙個類,來完成對核心類的「裝飾」。

裝飾模式的要點:

1. 簡單情況下,核心功能的component類和裝飾類,都可以不需要抽象成父類。但是,因為客戶眼中始終還是在操作這個核心功能類(客戶當然不應該在裝飾後就拿到乙個其它型別),所以裝飾類需要繼承元件類,在裝飾後應依然以元件類形式返回給客戶呼叫。

2. 「繼承的是型別,而不是行為」:繼承元件介面,僅僅是為了讓客戶始終呼叫同乙個型別。除此之外,裝飾類還必須包含乙個元件物件。這裡也是乙個用合成且不能用繼承的例子。可以想想,假如有100個額外功能的排列組合,使用繼承但不合成的話,那豈不是要出現100個排列組合的所有可能的子類?顯然是不合適的,這也就是所說的「繼承是靜態的而非動態的」

3.多個裝飾類的呼叫順序應該按照實際的業務邏輯來進行,順序錯誤是不可接受的。例如先穿襯衣再穿外套,在**上會形成一條裝飾器鏈。

下面是對裝飾模式的一些討論:

與builder建造者模式的區別?

builder是為了提供乙個物件,這個物件的建立過程複雜,但也是固定的,建立好了物件才能用。 而decorator則是在獲得物件後,去裝配一些可有可無的額外功能,是動態的靈活的,這時候builder那種固定的建立邏輯就不適用了。

與bridge橋接模式的區別?

橋接是因為乙個產品的建立存在多個維度,每個維度有自己的一系列變化,我們必須把這些維度解耦出來,避免類的不斷增加。所以橋接就是把產品拆分,然後通過合成聚合等方式組合起來。各自維護自己維度,並沒有什麼介面的繼承關係在裡頭。

與adapter介面卡模式的區別?

介面卡,是為了將源物件改造成適合客戶端使用的新的介面,介面已經改變了。而裝飾模式,強調的是使用原介面。 其實,這兩種模式很類似,也沒有特別明確的界限。介面卡是為了改變介面,但不在意改變功能。裝飾器的目的在於改變(新增額外)功能,但不會去改變介面。實際中可能存在裝飾器實現類中增加了額外的介面,而且核心元件component的功能也被增加的情況,這時候如果客戶要使用額外介面,就必須使用裝飾器類了,這種情況component並非完全對使用者透明,稱作半透明裝飾器。

與proxy**模式的區別?

**類將被**的類封裝在其中,兩者實現同乙個介面。客戶使用介面持有**類,完全遮蔽了被**類的所有細節。也就是說**類控制了被**物件。

但裝飾器做不到,component元件是客戶建立的,然後再由裝飾器鏈層層包裝,客戶能夠直接操作核心物件。

設計模式之Decorator 家裝篇

設計模式之 decorator 家裝篇 最近家裡搞裝修,做了一套家具,需要刷一下漆,因此我就去市場找了油漆師傅和油漆徒弟兩個人。油漆師傅主要買油漆和調油漆,油漆徒弟主要來 刷油漆 團隊精神?哈哈,不禁讓讓我想起 cs,你先衝,我揀菜。1 在這裡,我們先把這個油漆工作定義成乙個介面類 public i...

Decorator設計模式

雖然設計模式分得太細會有過度的趨勢,decorator某種程度上也是一種facade模式。但是實現起來還是比較漂亮的。而後面那個人的class arlist list,ilist的方法就不是decorator。它沒有乙個內部的list。這樣 however,now all of list s met...

設計模式 decorator模式

裝飾者模式體現了 敏捷開發思想中的 對類要 開放擴充套件,關閉修改.例子 乙個person主類 若干裝飾品類 紅衣服,藍衣服,藍鞋子,紅鞋子 測試 new乙個person 給他穿上紅衣服藍鞋子 code person介面 public inte ce ipersonperson類 package c...