装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
示例—咖啡店
因为扩张速度实在太快了,他们准备更新订单系统,以合乎他们的饮料供应要求。
Beverage(饮料)是一个现有抽象类,店内所提供的饮料都必须继承自此类。Beverage包括一个description属性、getDescription实例方法、抽象方法cost等等。
购买咖啡时,也可以要求在其中加入各种调料,例如:蒸奶(Steamed Milk)、豆浆(Soy)、摩卡(Mocha,也就是巧克力风味)或覆盖奶泡。他们会根据所加入的调料收取不同的费用。所以订单系统必须考虑到这些调料部分。
UML图表示

代码演示
abstract class Beverage{
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
/**
* 浓缩咖啡
*/
class Espresso extends Beverage {
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
/**
* 混合咖啡
*/
class HouseBlend extends Beverage {
public HouseBlend(){
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
/**
* 深烘焙咖啡
*/
class DarkRoast extends Beverage {
public DarkRoast(){
description = "Dark Roast Coffee";
}
@Override
public double cost() {
return .99;
}
}
/**
* 低咖啡因咖啡
*/
class Decaf extends Beverage {
public Decaf(){
description = "Decaf Coffee";
}
@Override
public double cost() {
return 1.05;
}
}
/**
* 摩卡
*/
class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return .20 + beverage.cost();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
}
/**
* 牛奶
*/
class Milk extends CondimentDecorator{
Beverage beverage;
public Milk(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return .10 + beverage.cost();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
}
/**
* 豆浆
*/
class Soy extends CondimentDecorator{
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return .15 + beverage.cost();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
}
/**
* 奶泡
*/
class Whip extends CondimentDecorator{
Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return .10 + beverage.cost();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
}
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
网友评论