
一、介绍
装饰器模式(Decoration Pattern),属于结构型设计模式 ,用于在不改变现有对象 的基础上,对该对象的方法动态 地添加新的功能,实现对该对象原有方法的增强
装饰器模式的设计思想是将对象的核心功能 和附加功能独立开来。核心功能由现有对象提供,附加功能由装饰器提供。
装饰器的实现思路是存在一个抽象的装饰器类 ,该装饰器类用于对现有的对象进行包装,然后通过该装饰器的具体子类对包装的类的方法进行增强。推而论之,在存在多个装饰器具体子类的情况下,可以动态地对现有对象随心所欲进行嵌套包装,对现有对象进行包装后,可以在已包装基础上进行多层嵌套包装
二、主要角色
在装饰器模式中,主要包含以下四个角色:
- 核心组件抽象接口(Component)
规定了被装饰对象的行为。
- 核心组件具体实现(ComponentImpl)
实现核心组件抽象接口,对接口规定的行为进行具体实现。
- 抽象装饰器(AbsDecoration)
通用的装饰ComponentImpl的装饰器,该装饰器必须包含一个以被装饰对象为参数的构造方法。
该装饰器设定为抽象类的原因是通过其构造函数管理被装饰的对象,以此来限制具体装饰器的构造方法必须传入被装饰的对象。
- 具体装饰器(Decoration)
继承抽象装饰器。用于增强对被装饰对象某一功能的特定装饰逻辑

三、案例
核心组件抽象接口
public interface Coffee {
/**
* 获取描述信息
*/
String getDescription();
/**
* 获取花费
*/
double getCost();
}
核心组件具体实现
黑咖啡 就是核心
java
public class BlackCoffee implements Coffee{
@Override
public String getDescription() {
return "黑咖啡";
}
@Override
public double getCost() {
return 10;
}
}
抽象装饰器
java
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double getCost() {
return coffee.getCost();
}
}
具体装饰器
给咖啡加牛奶
java
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription()+ " 加奶";
}
@Override
public double getCost() {
return super.getCost()+ 5 ;
}
}
给咖啡加糖
java
public class SugarDecorator extends CoffeeDecorator{
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", 加糖";
}
@Override
public double getCost() {
return super.getCost() + 2;
}
}
测试

在存在多个装饰器具体子类的情况下,可以动态地对现有对象随心所欲进行嵌套包装
上面的例子也可以加2分牛牛奶一份糖,可以随心所欲的进行装饰。
四、装饰器模式在jdk的应用
java中的IO是明显的装饰器模式的运用。FilterInputStream,FilterOutputStream,FilterRead,FilterWriter分别为具体装饰器的父类,相当于Decorator类,它们分别实现了InputStream,OutputStream,Reader,Writer类(这些类相当于Component,是其他组件类的父类,也是Decorator类的父类)。
继承自InputStream,OutputStream,Reader,Writer这四个类的其他类是具体的组件类,每个都有相应的功能,相当于ConcreteComponent类。而继承自FilterInputStream,FilterOutputStream,FilterRead,FilterWriter这四个类的其他类就是具体的装饰器对象类,即ConcreteDecorator类。通过这些装饰器类,可以给我们提供更加具体的有用的功能。如FileInputStream是InputStream的一个子类,从文件中读取数据流,BufferedInputStream是继承自FilterInputStream的具体的装饰器类,该类提供一个内存的缓冲区类保存输入流中的数据。我们使用如下的代码来使用BufferedInputStream装饰FileInputStream,就可以提供一个内存缓冲区来保存从文件中读取的输入流
①组件接口,相当于Component:
InputStream
OutputStream
Reader
Writer
②组件的实现类,相当于ConcreteComponent
FileInputStream
③装饰器接口,相当于Decorator
FilterInputStream
FilterOutputStream
FilterRead
FilterWriter
④装饰器类
BufferedInputStream继承自FilterInputStream
使用说明:我们可以用BufferedInputStream修饰FileInputStream


例如
java
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
//其中file为某个具体文件的File或者FileDescription对象
java
FileWriter file = new FileWriter("sample.txt");
BufferedWriter writer = new BufferedWriter(file);
writer.write("a small amount of sample text");
writer.newLine();
writer.close();
五、优缺点
优点:
由于装饰器对象和被装饰的对象都实现于核心抽象接口,根据面向接口编程原则,它们具有相同的行为。
装饰器不仅可以将已有对象进行包装,也可以对装饰器对象嵌套包装。
通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
避免多个被装饰对象与装饰器而导致最终类数量上的膨胀。
缺点:
每当为被装饰对象添加新的功能,都需要为其新建一个装饰类
六、适用场景
动态功能扩展: 运行时为对象添加或移除功能(如日志、缓存、加密)
避免多层继承: 替代复杂的继承树(如 BufferedFileReader、EncryptedFileReader)
透明性要求: 客户端无需感知对象是否被装饰(保持接口一致性)。
功能组合复用: 支持多种功能的自由组合(如 压缩 + 加密 文件流)