適用環境舉例:星巴茲咖啡的飲料需要加入牛奶、奶泡、豆漿等調料,加入這些調料之後價錢需要有所改變,現在所有的飲料都是繼承自Beverage類。
設計原則:對擴展開放,對修改關閉。
主要使用於:動態的將責任附加到對象上,想要擴展功能裝飾者提供有別於集成的另一種選擇。
注意:
1、裝飾者和被裝飾者對象必須繼承自同一個類。
2、可以用多個裝飾者裝飾同一個對象。
3、裝飾者模式可以動態的將責任附加到對象上。若要擴展功能,裝飾者提供了逼繼承更有彈性的替代方案。
4、裝飾者都有一個實例變量來保存被裝飾者。
真實世界的裝飾者:java I/O
FileInputStream是一個組件,BufferedInputStream是一個裝飾者,它加入了readLine()方法,LineNumberInputStream 也是一個裝飾者,它加上了計算行數的能力。
BufferedInputStream、LineNumberInputStream 都擴展自FileInputStream,FileInputStream是一個抽象的裝飾者,類似於CondimentDecorator 。
java I/O中使用了大量的裝飾者模式。
以下爲實例源碼(具體請參見head first 設計模式):
public abstract class Beverage {//飲料對象
String description = "Unknown Beverage";
public String getDescription() {//獲取描述
return description;
}
public abstract double cost();//獲取價錢。
}
public abstract class CondimentDecorator extends Beverage {//所有的調料對象都繼承飲料對象,必須實現描述的方法。
public abstract String getDescription();
}
public class Espresso extends Beverage {//濃縮咖啡
public Espresso() {
description = "Espresso";
}
public double cost() {
return 1.99;
}
}
public class HouseBlend extends Beverage {//另外一種飲料
public HouseBlend() {
description = "House Blend Coffee";
}
public double cost() {
return .89;
}
}
public class Mocha extends CondimentDecorator {//裝飾者 摩卡
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return .20 + beverage.cost();
}
}
public class StarbuzzCoffee {
public static void main(String args[]) {
Beverage beverage = new Espresso();//僅僅一杯咖啡
System.out.println(beverage.getDescription()
+ " $" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);//被摩卡和奶泡裝飾了的咖啡
System.out.println(beverage2.getDescription()
+ " $" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);//被摩卡 奶泡 豆漿裝飾了的咖啡。
System.out.println(beverage3.getDescription()
+ " $" + beverage3.cost());
}
}
輸出
Espresso $1.99
Dark Roast Coffee, Mocha, Mocha, Whip $1.49
House Blend Coffee, Soy, Mocha, Whip $1.34