1、概念描述
该模式以对客户端透明的方式扩展对象的功能。
装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者和被装饰者必须是一样的类型,这是相当关键的地方。我们利用继承达到"类型匹配",而不是利用继承获得"行为"。装饰者和被装饰者需具有相同的"接口",使得装饰者能够取代被装饰者;他们的行为,是通过组件之间的组合得到的。
涉及的角色:
(1)抽象构件角色:定义一个抽象接口,来规范准备附加功能的类。
(2)具体构件角色:将要被附加功能的类,实现抽象构件角色接口。
(3)抽象装饰者角色:持有对具体构件角色的引用并定义与抽象构件角色一致的接口。
(4)具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能。
注意点:
(1)装饰者和被装饰者必须具有相同的超类型。
(2)装饰者即可以包装被装饰者,也可以包装装饰者。往往利用多层包装来达到目的。
(3)装饰者中组合了被装饰者对象,这是装饰类的关键特征。正是由于这种组合,使得我们能够随心所欲的通过嵌套装饰来动态扩展行为。
2、实例
(1)、根据《Head First 设计模式》 装饰者模式应用到“星巴兹”咖啡店,类图如下
(2)、主体coffee
public abstract class Coffee {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
(3)、被装饰者BrazilCoffee、JavaCoffee、Cappuccnio
public class BrazilCoffee extends Coffee {
public BrazilCoffee(){
description ="BrazilCoffee";
}
@Override
public double cost() {
return 1.99;
}
}
public class JavaCoffee extends Coffee {
public JavaCoffee() {
description = "JavaCoffee";
}
@Override
public double cost() {
return 0.89;
}
}
public class Cappuccnio extends Coffee {
public Cappuccnio(){
description = "Cappuccnio";
}
@Override
public double cost() {
return 0.77;
}
}
(4)、装饰者类CoffeeDecorator
public abstract class CoffeeDecorator extends Coffee {
public abstract String getDescription();
}
(5)、具体装饰者类Milk、Mocha
public class Milk extends CoffeeDecorator {
Coffee cooffee;
public Milk(Coffee cooffee) {
this.cooffee = cooffee;
}
@Override
public String getDescription() {
return cooffee.getDescription() + ", Milk";
}
@Override
public double cost() {
return 0.1 + cooffee.cost();
}
}
public class Mocha extends CoffeeDecorator {
Coffee cooffee;
public Mocha(Coffee cooffee) {
this.cooffee = cooffee;
}
@Override
public String getDescription() {
return cooffee.getDescription() + ", Mocha";
}
@Override
public double cost() {
return 0.2 + cooffee.cost();
}
}
......
(6)、测试类
public static void main(String[] args) {
Coffee coffee = new JavaCoffee();
coffee = new Milk(coffee);
coffee = new Mocha(coffee);
System.out.println(coffee.getDescription() + "$" + coffee.cost());
}
(7)、结果
----------------------------------------
JavaCoffee, Milk, Mocha$1.19
----------------------------------------