Java設計模式之裝飾者模式

2021-08-21 13:13:10 字數 2239 閱讀 8380

設想乙個情景,假設有一家奶茶店,店裡面只賣飲料,不賣其他的東西,且飲料的品種只有兩種分別為coffee和milk,那麼為這家店的訂單系統可以簡單的設計為兩個類,coffee類和milk類。如果有一天,店裡面賣的飲料品種增加了很多種,這個時候我們可以發現飲料種類很多,但是每一類都可以抽象出類似的屬性和方法,每個種類都有乙個描述該類飲料的屬性description以及乙個獲取**的方法cost()。於是我們抽象出來乙個抽象類(或者介面)drink,並且讓每個種類的飲料都繼承drink(或實現drink介面)。

public abstract class drink 

public abstract float cost();

}

public class coffee extends drink 

@override

public float cost()

}

public class milk extends drink 

@override

public float cost()

}

這樣之後,以後每增加乙個品種,只需要繼承drink類就可以了。

但是,有一天,店主為了增加銷量,提出了乙個新的主意,那就是可以在飲料裡面新增各種各樣的配料,諸如chocolate和sugar等,每一種調料都有各自的**。這樣一來,不同品種可以加上不同的調料,最終的**也就各不相同。那麼此時如何改進這個訂單系統比較好呢。

一種方式是為每一種主料和各種配料的組合實現乙個新的飲料品種類,比如coffee+sugar類,milk+chocolate類,coffee+sugar+chocolate類。但是這樣一來,當主料和配料的種類較多之後,類的數量將呈現乙個**式的增長。更不好的是,假設當某一種主料或者配料的**發生了變化時,需要維護的類的數量是巨大的。所以,這種設計是非常糟糕的。

這個時候,裝飾者模式就可以派上用場了。什麼是裝飾者模式呢,就以這個例子來說,我們的milk類和coffee類是飲料的一種,所以我們讓他們從drink類繼承。另外我們還有各種各樣可以新增的配料,雖然配料不是飲料,但是我們可以想象,某個品種的飲料在新增了某一種或多種的配料之後,它仍然是屬於一種飲料。所以我們將配料(sugar、chocolate等)也繼承自drink類。(或許,將sugar類的名稱改為adrinkaddsugar更容易理解)。表示新增了此種配料的一種飲料。

這樣一來,不管是主料還是配料全都繼承(或實現)了drink,我們就可以在每個配料的類裡面增加乙個drink型別的變數,這個變數指的就是需要新增此種配料的飲料的乙個引用(有可能這個飲料之前已經新增過了其他的配料,但是無所謂,所有的主料配料都繼承了drink,所以它仍然是一種drink)。這樣一來,我們在配料的description和cost()方法裡面,就可以根據這個引用獲取新增此配料之前的相關資訊(如品種描述和**等),然後在這個配料類裡面加上有關這個配料的資訊。

這樣一來,我們只需要維護很少的類就可以實現相同的功能。下面是例子**:

public class sugar extends drink 

public string getdescription()

@override

public float cost()

}

public class chocolate extends drink 

public string getdescription()

@override

public float cost()

}

下面是測試**,首先我們建立了乙個牛奶的飲料,列印出相關的資訊。然後我們根絕這個牛奶建立了一杯milk+sugar的飲料,並列印出了它的相關資訊,最後我們又根據這杯加過了sugar的飲料建立了一杯加了chocolate的飲料。

public class test 

}

程式執行結果如下:

milk:10.0

milk+sugar:12.0

milk+sugar+chocolate:15.0

那麼為什麼這種模式叫裝飾者模式呢?我們可以從測試程式看出,我們首先是建立了一杯只含有主料的飲料,接下來我們是對這杯飲料新增了各種各樣的配料,就好像是我們有一間空房子,我們買了各種各樣的東西來裝飾它一樣。裝飾的順序可以有所不同,但是裝飾之後它仍然是一間房子,我們仍然可以繼續對它進行裝飾。

在jdk中,io流部分就是用了大量的裝飾者模式!

java設計模式之裝飾者模式

裝飾者模式 動態的將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。類圖 barbecue類 實現 package com.decorator public abstract class barbecue public abstract double cost fish類 ...

Java設計模式之裝飾者模式

裝飾者模式在保持原有結構不變的情況下,新建類 新增功能 去包裝原有的類。1.實體抽象類 public inte ce drink 2.具體例項實現 public class coffee implements drink override public string getdescription 3...

Java設計模式之裝飾者模式

裝飾者模式在我理解就是物件功能的封裝和傳遞的過程。我們去花店買花送人的時候會首先選哪種花,比如送老婆選的紅玫瑰,送媽媽的康乃馨等等,然後包裝走人 如果你想送大一點的,那你就得買其他的去搭配,比如101朵玫瑰,外加一些荷蘭百合,總之我們會買更多的花 在模式中我們認為有更多的操作 讓它能夠成為一束花,然...