-
目的:爲對象動態添加功能。
-
說明:裝飾者(Decorator)和具體組件(ConcreteComponent)都繼承自組件(Component),具體組件的方法實現不需要依賴於其它對象,而裝飾者組合了一個組件,這樣它可以裝飾其它裝飾者或者具體組件。所謂裝飾,就是把這個裝飾者套在被裝飾者之上,從而動態擴展被裝飾者的功能。裝飾者的方法有一部分是自己的,這屬於它的功能,然後調用被裝飾者的方法實現,從而也保留了被裝飾者的功能。可以看到,具體組件應當是裝飾層次的最低層,因爲只有具體組件的方法實現不需要依賴於其它對象。
-
實例
設計不同種類的飲料,飲料可以添加配料,比如可以添加牛奶,並且支持動態添加新配料。每增加一種配料,該飲料的價格就會增加,要求計算一種飲料的價格。
下圖表示在 DarkRoast 飲料上新增新添加 Mocha 配料,之後又添加了 Whip 配料。DarkRoast 被 Mocha 包裹,Mocha 又被 Whip 包裹。它們都繼承自相同父類,都有 cost() 方法,外層類的 cost() 方法調用了內層類的 cost() 方法。
接口
public interface Beverage {
double cost();
}
被裝飾者
public class HouseBlend implements Beverage {
@Override
public double cost() {
return 1;
}
}
抽象裝飾者
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
}
具體裝飾者
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
客戶端
public class Client {
public static void main(String[] args) {
Beverage beverage = new HouseBlend();
beverage = new Mocha(beverage); //擴展類功能
beverage = new Milk(beverage);
System.out.println(beverage.cost());
}
}