裝飾者模式

2021-07-27 12:43:57 字數 3266 閱讀 5190

裝飾者模式:動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。這種設計屬於結構型設計模式,而上一節所講的觀察者模式屬於行為型模式。

《head first 設計模式》書中舉了咖啡的例子:店中有各種各樣的咖啡各類,比如黑咖啡、白咖啡……(此處筆者亂起的名字,不要在意),然後顧客會在這些咖啡的基礎上加各種調料組合成各式各樣的bevetage,ok,現在問題來了,比如要怎麼算錢呢?要怎樣實現這各種各樣的新式組合咖啡呢?如果以bevetage為基類,同時每一種組合咖啡都在繼承基類的基礎上來建立乙個實體類,那就有太多組合了,類就太多太多了,對吧?如圖4、5所示。現在就要我們的裝飾者模式出場了:

figure4 beverage類圖

figure5 beverage 子類

此處我們利用繼承無法合適地解決這個問題,因為用繼承會有很多問題:類數量**、設計死板等。因此,我們採用以beverage為主體,然後在執行時以調料「裝飾」飲料。比如顧客要摩卡和奶泡深焙咖啡,那麼,要做的是:

1.        拿乙個深焙咖啡(darkroast)物件

2.        以摩卡(mocha)物件裝飾它

3.        以奶泡(whip)物件裝飾它

4.        呼叫cost()方法,並依賴委託(delegate)將調料的價錢加上去

ok,現在我們總結下上面所說的:

1.        裝飾者和被裝飾者物件有相同的超型別。(這樣裝飾者可以替換被裝飾者)

2.        你可以用乙個或者多個裝飾者包裝乙個物件。

3.        既然裝飾者和被裝飾者物件有相同的超型別,所以在任何需要原始物件的場合,可以用裝飾過的物件代替它。

4.        裝飾者可以在所委託裝飾者的行為之前與之後,加上自己的行為,以達到特定的目的。(關鍵點)

5.        物件可以在任何時候被裝飾,所以可以在執行時動態地、不限量地用你喜歡的裝飾者來裝飾物件。

具體裝飾者的類圖如下所示:

figure6 裝飾者模式類圖

下面擼上上面咖啡的**:

/** 

* @classname: beverage

* @description: 飲料基類

* @author 春天畫花卉校長

* @date 2023年2月26日 下午9:10:11

* */

public abstract class beverage

public abstract double cost();

}

/** 

* @classname: condimentdecorator

* @description: 裝飾者基類,繼承beverage

* @author 春天畫花卉校長

* @date 2023年2月26日 下午9:06:28

* */

public abstract class condimentdecorator extends beverage

/** 

* @classname: espresso

* @description: 濃縮咖啡

* @author 春天畫花卉校長

* @date 2023年2月26日 下午9:07:30

* */

public class espresso extends beverage

@override

public double cost()

}

/** 

* @classname: houseblend

* @description: houseblend

* @author 春天畫花卉校長

* @date 2023年2月26日 下午9:12:30

* */

public class houseblend extends beverage

@override

public double cost()

}

public class mocha extends condimentdecorator 

@override

public string getdescription()

@override

public double cost()

}

public class coffeeshop 

}

執行結果:

在實際應用中,有好多地方用到了裝飾者模式,比如我們經常用的輸入輸出類。拿inputstream來看一下,如圖7:

figure7 inputstream類圖

它的基本原理跟上面我們講的咖啡例子差別不大,在這兒就不再贅述了。最後我們再總結一下裝飾者模式的有關問題:

1.        繼承屬於擴充套件形式之一,但不見得是達到彈性設計的最佳方式。

2.        在我們的設計中,應該允許行為可以被擴充套件,而無須修改現有的**。

3.        組合和委託可用於在執行時動態地加上新的行為。

4.        除了繼承、裝飾者模式也可以讓我們擴充套件行為

5.        裝飾者模式意味著一群裝飾者類,這些類用來包裝具體元件。

6.        裝飾者類反映出被裝飾的元件型別(事實上,他們具有相同的型別,都經過介面或者繼承實現)。

7.        裝飾者可以在被裝飾者的行為前面與後面加上自己的行為,甚至將被裝飾者的行為整個取代掉,而達到特定的目的。

8.        你可以用無數個裝飾者包裝乙個元件。

9.        裝飾者一般對元件的客戶是透明的,除非客戶程式依賴於元件的具體型別。

10.    裝飾者會導致設計中出現許多小物件,如果過度使用,會讓程式變得很複雜。

裝飾者模式

裝飾者模式 動態地將責任附加到物件上。若要擴張功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者可以在所委託被裝飾者的行為之前或之後,加上自己的行為,以達到特定的目的。裝飾者與被裝飾者物件具有相同的超型別。include include using namespace std class bever...

裝飾者模式

裝飾者模式,是在不改變原類檔案和使用繼承的情況下,動態地擴充套件乙個物件的功能。它是通過建立乙個包裝物件,也就是裝飾來包裹真實的物件。裝飾者模式中的角色 1 被裝飾者抽象component,是乙個介面或抽象類,就是定義最核心的物件,也是最原始的物件,這個類是需要裝飾類的基類。2 被裝飾者具體實現co...

裝飾者模式

裝飾者模式 裝飾者模式的好處是便於擴充套件,對乙個東西不管怎麼變,只需要找到相應的元件去改變它 1.如何組裝在一起 建立主題 packetbodycreator body new packetbodycreator 建立header packethtmlheadercreator html new ...