iT邦幫忙

0

裝飾者模式的原理

  • 分享至 

  • xImage

就是我最近在看JAVA IO,而JAVA IO大量地使用裝飾者模式來實作 所以我也看了

裝飾者模式的原理,我看了好幾個文章跟影片,裡面都會說到裝飾者類別(Decorate)

和被裝飾者類別(Component),是繼承+組合的關係,組合的部分指的是裝飾者包含了

要被裝飾的物件,

例如咖啡是被裝飾者,牛奶是裝飾者,那麼牛奶這個類別就會包含咖啡這個物件;也就是

public class Milk{

        private Coffee coffee;
        ......
}

又例如主菜是被裝飾者,小菜是裝飾者,那麼小菜這個類別就包含主菜物件

但是我不能理解的是,如果code寫成以上那樣,那就表示牛奶has a咖啡;

但在邏輯上牛奶或是小菜又不包含咖啡和主菜

我的想法是牛奶本身跟咖啡沒有has a的關係,不能說成是牛奶has a咖啡;

而小菜跟主菜也不是has a的關係,也不能說成是小菜has a主菜,

是因為現在牛奶裝飾咖啡,所以牛奶has a咖啡??這樣的話為甚麼不能是咖啡has a牛奶

讓咖啡類別去包含牛奶屬性??

所以我的問題是,

為什麼咖啡跟牛奶,主菜和小菜會有這種組合關係,或者是說has a的關係?

另外就是,為什麼裝飾者,這裡就是牛奶和小菜,需要去繼承抽象的被裝飾類(Component)

這樣牛奶和小菜就去繼承到咖啡主菜共同的屬性方法,這個繼承的邏輯或目的是??

所以我在這個抽象的裝飾者類,他的繼承和組合關係搞不懂。

還有一個問題,就是裝飾者模式相較於繼承,可以降低耦合度,是因為要擴充功能的話,

不用改到既有的程式,而是增加裝飾者就好嗎?如果真是這樣,那難道用了裝飾者模式,

就都不會有修改既有程式的需求,就一直增加裝飾者??

例如咖啡不用動,就一直增加牛奶、豆漿、巧克力......等配料(裝飾者)。

應該不會有完全不會動到咖啡的狀況,那這樣降低耦合度是體現在哪呢??

我是看以下的影片:

https://www.youtube.com/watch?v=Ft6IMa04Nj4

這支影片一開始前幾秒的地方

https://www.youtube.com/watch?v=J3_IKZLuyoI

這支影片大約15分30秒的地方

都列出了Decorate繼承Component的圖,其中第一個影片還特別提到繼承+組合的關係。

還有以下文章:

https://www.itread01.com/content/1547400429.html

https://matthung0807.blogspot.com/2018/11/java-decorator-pattern.html

一樣列出了Decorate繼承Component的圖

就是這個繼承+組合搞不懂,我上面的解釋都是圍繞著這個圖在說明。

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
I.T. Wang
iT邦新手 1 級 ‧ 2022-02-06 13:34:40

你的發問比較學術化,IT邦比較實務化,建議你的問題還是請教你的教授比較快

0
石頭
iT邦高手 1 級 ‧ 2022-02-06 17:34:15

裝飾者模式 有兩個主要角色

  • 被裝飾物件(Decorated)
  • 裝飾物件(Decorator)

必須先釐清這兩個角色關係才有辦法繼續提取抽象,以 Java Io 來說我印象中他的 DecoratedStream.

雖然我寫的文章是 C# 裝飾者模式(Decorator Pattern)案例分析 但設計模式在於他的概念,語言只是表象

學習設計模式在我經驗 UML 圖目前不了解看不懂,可以先略過重點 先把模式要解決的問題了解

每種設計模式會存在就是為了解決某些問題,且這些問題常常會遇到

0
paooap6365
iT邦新手 5 級 ‧ 2022-02-11 03:02:11

但在邏輯上牛奶或是小菜又不包含咖啡和主菜
為什麼咖啡跟牛奶,主菜和小菜會有這種組合關係,或者是說has a的關係?

感覺是語意上理解的問題,你的邏輯已經建立在牛奶是牛乳,所以不該包含咖啡這個東西,如果今天的名稱叫做牛奶添加物,然後我們定義這個牛奶添加物可以包含其他飲料,不知道對你來說有沒有比較合理。

另外就是,為什麼裝飾者,這裡就是牛奶和小菜,需要去繼承抽象的被裝飾類(Component)
這樣牛奶和小菜就去繼承到咖啡主菜共同的屬性方法,這個繼承的邏輯或目的是??

我的理解是可以更好的解耦合。假設情境,今天需求是牛奶添加物+牛奶添加物+咖啡時,當你要用添加第二層裝飾時,不會被類別綁住。

就都不會有修改既有程式的需求,就一直增加裝飾者??
例如咖啡不用動,就一直增加牛奶、豆漿、巧克力......等配料(裝飾者)。
應該不會有完全不會動到咖啡的狀況,那這樣降低耦合度是體現在哪呢??

所有設計都是依據業務邏輯而生,沒有萬用解,假設今天你的老闆說我們的咖啡要會飛,那整個業務邏輯就不同了,勢必會需要修改。降低耦合的體現是在於當今天業務邏輯還符合原設計的情況下才有的優勢。

我要發表回答

立即登入回答