装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
设计原则:类应该对扩展开放,对修改关闭。
我们的目标是允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的需求。
类图
ConcreteComponent是我们要动态地加上新行为的对象,它扩展自Component。
每个装饰者都“有一个”(包装一个)组件,也就是说,装饰者有一个实例变量以保存某个Component的引用。
Beverage.java
/**
*Beverage(Component)是一个抽象类,有两个方法:getDescription()及cost()
*/
package headfirst.decorator.starbuzz;
public abstract class Beverage {
String description = "Unknown Beverage";
//getDescription()已在此实现,而cost需在子类中实现
public String getDescription() {
return description;
}
public abstract double cost();
}
CondimentDecorator.java
/**
*必须让Condiment Decorator能取代Beverage,所以CondimentDecorator扩展自Beverage类
*/
package headfirst.decorator.starbuzz;
public abstract class CondimentDecorator extends Beverage {
//所有调料装饰者必须重新实现getDescription()
public abstract String getDescription();
}
Espresso.java
/**
*ConcreteComponent扩展自Beverage
*/
package headfirst.decorator.starbuzz;
public class Espresso extends Beverage {
public Espresso() {
//description继承自Beverage
description = "Espresso";
}
public double cost() {
return 1.99;
}
}
Mocha.java
/*
*ConcreteDecorator继承自CondimentDecorator,而CondimentDecorator扩展自Beverage
*/
package headfirst.decorator.starbuzz;
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();
}
}