二、结构动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更加灵活。
装饰模式的结构如图7-34所示。
其中:
• Component定义一个对象接口,可以给这些对象动态地添加职责。
• ConcreteConiponent定义一个对象,可以给这个对象添加一些职责。
• Decorator维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
• ConcreteDecorator向组件添加职责。
Decorator模式适用于:
• 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
• 处理那些可以撤销的职责。
• 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是, 由于类定义被隐蔵,或类定义不能用于生成子类。
某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如下表所示。
现采用装饰器(Decorator)模式来实现计算费用的功能,得到如图 6-1 所示的类图
首先 创建饮料和配料两个抽象类。
abstract class Beverage { // 饮料
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract int cost() ;
}
abstract class CondimentDecorator extends Beverage { // 配料
Beverage beverage;
}
然后 用蒸馏咖啡和深度烘焙咖啡去继承饮料类。
class Espresso extends Beverage { // 蒸馏咖啡
private final int ESPRESSO_PRICE = 25;
public Espresso() {
description = "Espresso";
}
public int cost() {
return ESPRESSO_PRICE;
}
}
class DarkRoast extends Beverage { // 深度烘焙咖啡
private final int DARKROAST_PRICE = 20;
public DarkRoast() {
description = "DarkRoast";
}
public int cost() {
return DARKROAST_PRICE;
}
}
其次 用摩卡和奶泡继承配料类。
class Mocha extends CondimentDecorator { // 摩卡
private final int MOCHA_PRICE = 10;
public Mocha (Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public int cost() {
return MOCHA_PRICE + beverage.cost();
}
}
class Whip extends CondimentDecorator { // 奶泡
private final int WHIP_PRICE = 8;
public Whip (Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
public int cost() {
return WHIP_PRICE + beverage.cost();
}
}
最后 测试一下。
public class Decorator {
public static void main(String[] args) {
// TODO Auto-generated method stub
Beverage beverage1 = new Espresso();
beverage1 = new Mocha(beverage1);
System.out.println(beverage1.getDescription() +" ¥"+
beverage1.cost());
Beverage beverage2 = new Espresso();
beverage2 = new Whip (beverage2);
System.out.println(beverage2.getDescription() +" ¥"+
beverage2.cost());
Beverage beverage3 = new DarkRoast();
beverage3 = new Mocha(beverage3);
System.out.println(beverage3.getDescription() +" ¥"+
beverage3.cost());
Beverage beverage4 = new DarkRoast();
beverage4 = new Whip (beverage4);
System.out.println(beverage4.getDescription() +" ¥"+
beverage4.cost());
Beverage beverage5 = new Espresso();
beverage5 = new Mocha(beverage5);
beverage5 = new Whip (beverage5);
System.out.println(beverage5.getDescription() +" ¥"+
beverage5.cost());
Beverage beverage6 = new DarkRoast();
beverage6 = new Mocha(beverage6);
beverage6 = new Whip (beverage6);
System.out.println(beverage6.getDescription() +" ¥"+
beverage6.cost());
}
}
运行结果:



