1、定义
装饰器模式 允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。
属于结构型模式。
装饰器模式由四部分组成:
- 抽象组件(Component):需要装饰的抽象对象。
- 具体组件(ConcreteComponent):需要装饰的实体对象
- 抽象装饰类(Decorator):装饰的抽象类,内含指向抽象组件的引用及装饰者共有的方法。
- 具体装饰类(ConcreteDecorator):装饰的实体类,负责给实体对象增加新特性。
2、UML图
3、示例
1)Drink接口类:
public interface Drink {
public float cost();
public String getDescription();
}
2)Coffee类,需要被装饰的实体对象:
public class Coffee implements Drink {
final private String description = "coffee";
//每杯 coffee 售价 10 元
public float cost() {
return 10;
}
public String getDescription() {
return description;
}
}
3) CondimentDecorator 装饰的抽象类:
public abstract class CondimentDecorator implements Drink {
//对需要被装饰的实体类的引用
protected Drink decoratorDrink;
public CondimentDecorator(Drink decoratorDrink) {
this.decoratorDrink = decoratorDrink;
}
public float cost() {
return decoratorDrink.cost();
}
public String getDescription() {
return decoratorDrink.getDescription();
}
}
4)Milk 牛奶装饰类:继承了抽象类CondimentDecorator
public class Milk extends CondimentDecorator {
public Milk(Drink decoratorDrink) {
super(decoratorDrink);
}
@Override
public float cost() {
return super.cost() + 2;
}
@Override
public String getDescription() {
return super.getDescription() + " milk";
}
}
5)Sugar 装饰类:
public class Sugar extends CondimentDecorator {
public Sugar(Drink decoratorDrink) {
super(decoratorDrink);
}
@Override
public float cost() {
return super.cost() + 1;
}
@Override
public String getDescription() {
return super.getDescription() + " sugar";
}
}
测试代码:
public class CoffeeShop {
public static void main(String[] args) {
//点一杯coffee
Drink drink = new Coffee();
System.out.println(drink.getDescription() + ":" + drink.cost());
//加一份奶
drink = new Milk(drink);
System.out.println(drink.getDescription() + ":" + drink.cost());
//加一份糖
drink = new Sugar(drink);
System.out.println(drink.getDescription() + ":" + drink.cost());
//再加一份糖
drink = new Sugar(drink);
System.out.println(drink.getDescription() + ":" + drink.cost());
}
}
输出:
coffee:10.0
coffee milk:12.0
coffee milk sugar:13.0
coffee milk sugar sugar:14.0
4、应用场景
装饰模式(Decorator)也叫包装器模式(Wrapper)
装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。
适用于:1、扩展一个类的功能。 2、动态增加功能,动态撤销。
优点:
- 扩展对象功能,比继承灵活,不会导致类个数急剧增加
- 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
- 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类
缺点:
- 产生很多小对象。大量小对象占据内存,一定程度上影响性能
- 装饰模式易于出错,调试排查比较麻烦
Java IO流中有应用