歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java設計模式之---裝飾者模式

Java設計模式之---裝飾者模式

日期:2017/3/1 9:38:07   编辑:Linux編程

裝飾者模式,可以實現一個很重要的面向對象設計原則,那就是:類應該對擴展開放,而對修改關閉。換句話說,就是在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。但是在選擇需要被擴展的代碼部分時要小心,每個地方都采用開放-關閉原則是一種浪費,也沒必要,還會導致代碼變得復雜且難以理解。

大話設計模式(帶目錄完整版) PDF+源代碼 http://www.linuxidc.com/Linux/2014-08/105152.htm

Java中介者設計模式 http://www.linuxidc.com/Linux/2014-07/104319.htm

Java 設計模式之模板方法開發中應用 http://www.linuxidc.com/Linux/2014-07/104318.htm

設計模式之 Java 中的單例模式(Singleton) http://www.linuxidc.com/Linux/2014-06/103542.htm

跟JBPM學習設計模式 http://www.linuxidc.com/Linux/2014-06/102861.htm

舉個例子,比如,顧客想要摩卡和奶泡的深焙咖啡,那麼要做的是:

1,拿一個深焙咖啡(DarkRoast)對象

2,以摩卡(Mocha)對象裝飾它

3,以奶泡(Whip)對象裝飾它

4,調用cost()方法,並依賴委托(delegate)將調料的價錢加上去

Mocha對象是一個裝飾者,它的類型“反映”了它所裝飾的對象(本例中,就是Beverage)。所謂的“反映”,指的就是兩者類型一致。所以Mocha也有一個cost()方法,通過多態,也可以把Mocha所包裹的任何Beverage當成是Beverage(因為Mocha是Beverage的子類型)。

Whip同樣也是一個裝飾者,所以它也反映了DarkRoast類型,並包括一個cost()方法。

所以,被Mocha和Whip包起來的DarkRoast對象仍然是一個Beverage,仍然可以具有DarkRoast的一切行為,包括調用它的cost()方法。

現在該是為顧客算錢的時候了。通過調用最外圈裝飾者(whip)的cost()就可以辦得到。Whip的cost()會先委托它裝飾的對象(也就是Mocha)計算出價錢,然後再加上奶泡的價錢。

也就是說,

1,先調用最外圈裝飾者Whip的cost();

2,Whip調用Mocha的cost();

3,Mocha調用DarkRoast的cost();

4,DrakRoast返回它的價錢;

5,Mocha在DarkRoast的結果上,加上自己的價錢,返回新的價錢;

6,Whip在Mocha的返回結果上加上自己的價錢,然後返回最後結果;

注意,

1,裝飾者和被裝飾者有相同的超類型;

2,你可以用一個或多個裝飾者包裝一個對象;

3,既然裝飾者和被裝飾者有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象代替它;

4,裝飾者可以在委托被裝飾者的行為之前與/或之後,加上自己的行為,以達到特定的目的;

5,對象可以在任何時候被裝飾,所以可以在運行時動態地、不限量地用你喜歡的裝飾者來裝飾對象;

裝飾者模式,動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

下面我們開始代碼實現:

首先是Beverage類:

package decorator;

public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}

然後我們設計裝飾者類,Condiment抽象類:

package decorator;

public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}

現在已經有了基類,於是我們來實現一些飲料:

比如意大利特濃:

package decorator;

public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
public double cost(){
return 1.99;
}
}

比如綜合咖啡(星巴克獨家調配咖啡):

package decorator;

public class HouseBlend extends Beverage{
public HouseBlend(){
description="House Blend Coffee";
}
public double cost(){
return .89;
}
}

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-10/108750p2.htm

Copyright © Linux教程網 All Rights Reserved