Skip to content
进阶

一句话答案

动态给对象添加职责比继承更灵活,Java IO 流(BufferedReader 装饰 InputStreamReader)是典型应用。

核心要点

装饰器模式在不改变原始对象结构的情况下,动态地给对象添加新功能。装饰器和被装饰者实现相同的接口/继承相同的抽象类,装饰器内部持有被装饰对象的引用。

核心结构:

Component(抽象组件)
├── ConcreteComponent(被装饰的具体对象)
└── Decorator(装饰器抽象类,持有 Component 引用)
    ├── ConcreteDecoratorA
    └── ConcreteDecoratorB

装饰器 vs 继承:

维度装饰器模式继承
扩展方式运行时动态组合编译期静态确定
灵活性可自由搭配多个装饰器类爆炸(每种组合一个子类)
开闭原则遵守(新增装饰器即可)可能违反

Java IO 中的装饰器模式:

Java IO 是装饰器模式最经典的应用。InputStream 是抽象组件,FileInputStream 是具体组件,各种 FilterInputStream 子类是装饰器:

InputStream(抽象组件)
├── FileInputStream(具体组件:读文件)
├── ByteArrayInputStream(具体组件:读字节数组)
└── FilterInputStream(装饰器基类)
    ├── BufferedInputStream(增加缓冲功能)
    ├── DataInputStream(增加读取基本类型功能)
    └── PushbackInputStream(增加回退功能)
java
// 装饰器的层层包装——给 FileInputStream 添加缓冲 + 数据类型读取能力
InputStream is = new DataInputStream(
    new BufferedInputStream(
        new FileInputStream("data.bin")
    )
);
// FileInputStream: 负责从文件读取原始字节
// BufferedInputStream: 装饰器,增加了缓冲区(默认 8KB)减少磁盘 IO
// DataInputStream: 装饰器,增加了 readInt()/readDouble() 等方法

关键区分——装饰器 vs 代理:

  • 装饰器:增强功能,不改变接口语义(BufferedInputStream 加了缓冲但还是 InputStream)
  • 代理:控制访问,可能加权限检查、远程调用等(AOP 代理控制方法调用)
追问与易错

追问方向:

  • Java IO 中怎么体现?
  • 和继承比优势?
  • 和代理关键区别?

易错点:

  • ❌ 装饰器和代理一样——意图不同增强 vs 控制
  • ❌ 装饰器只能嵌套一层——可以多层

💡 记忆锚点

煎饼摊加料:基础煎饼(FileInputStream)加一层鸡蛋(BufferedInputStream加缓冲)再加一层肠(DataInputStream加类型读取),层层包裹但本质还是煎饼(InputStream),比继承灵活——继承等于把所有配料焊死在一种煎饼上。