装饰器模式动态地将责任附加到对象上。想要扩展功能,装饰器提供于继承有别的另一种选择
java类图
java代码
// 饮料抽象类
public abstract class Beverage {
protected String description = "Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
// 烘焙咖啡
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast Coffee";
}
@Override
public double cost() {
return 0.99;
}
}
// 低咖啡因咖啡
public class Decaf extends Beverage {
public Decaf() {
description = "Decaf Coffee";
}
@Override
public double cost() {
return 1.05;
}
}
// 浓缩咖啡
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso Coffee";
}
@Override
public double cost() {
return 1.99;
}
}
// 混合咖啡
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return 0.89;
}
}
// 配料装饰器
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
// 牛奶配料
public class Milk extends CondimentDecorator {
private Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Milk";
}
@Override
public double cost() {
return beverage.cost() + 0.1;
}
}
// 摩卡配料
public class Mocha extends CondimentDecorator {
private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Mocha";
}
@Override
public double cost() {
return beverage.cost() + 0.2;
}
}
// 豆浆配料
public class Soy extends CondimentDecorator {
private Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Soy";
}
@Override
public double cost() {
return beverage.cost() + 0.15;
}
}
// 奶泡配料
public class Whip extends CondimentDecorator {
private Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " ,Whip";
}
@Override
public double cost() {
return beverage.cost() + 0.1;
}
}
// 测试类
public class Test {
public static void main(String[] args) {
new Test().test();
}
private void test() {
Beverage espresso = new Espresso();
System.out.println(espresso.getDescription() + " $" + espresso.cost());
Beverage darkRoast = new DarkRoast();
darkRoast = new Mocha(darkRoast);
darkRoast = new Mocha(darkRoast);
darkRoast = new Whip(darkRoast);
System.out.println(darkRoast.getDescription() + " $" + darkRoast.cost());
Beverage houseBlend = new HouseBlend();
houseBlend = new Soy(houseBlend);
houseBlend = new Mocha(houseBlend);
houseBlend = new Whip(houseBlend);
System.out.println(houseBlend.getDescription() + " $" + houseBlend.cost());
}
}
注:
- 装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
- 装饰者反映出被装饰者的类型(事实上,他们具有相同的类型,都经过接口或者继承实现)。
- 装饰者可以在被装饰者的行为前面/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
- 你可以用无数个装饰者包装一个组件。
- 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
- 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。
参考文章
Head First 设计模式