结构型 中等

装饰器模式

Decorator Pattern

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

概述

装饰器模式是一种结构型设计模式,允许你通过将对象放入包含行为的特殊包装对象中来为原对象绑定新的行为。

适用场景

  • 当需要在运行时动态添加功能时
  • 当需要扩展一个类的功能,但继承不是可行选项时
  • 当需要为对象添加多个可以独立变化和组合的额外功能时
  • 当不能或不方便使用继承来扩展功能时(如类被 final 修饰)

优点

  • +可以在运行时添加或删除对象的功能
  • +可以用多个装饰器包装对象,实现功能的自由组合
  • +单一职责原则:将功能划分为不同类,每个类只负责一项功能
  • +开闭原则:无需修改现有代码即可扩展对象的行为
  • +比继承更灵活,避免了类爆炸问题

缺点

  • 在装饰器栈中删除特定装饰器比较困难
  • 实现行为不受装饰器栈顺序影响的装饰器可能很困难
  • 代码调试可能变得复杂,因为需要跟踪多层包装
  • 可能会产生大量的小类,增加系统复杂度

结构

classDiagram class Component { <<interface>> +operation() string } class ConcreteComponent { +operation() string } class Decorator { -component: Component +operation() string } class BorderDecorator { -borderWidth: number +operation() string +drawBorder() } class ScrollDecorator { -scrollPosition: number +operation() string +scrollTo() } class ShadowDecorator { -shadowColor: string -shadowBlur: number +operation() string +applyShadow() } class Client { +main() } Component <|.. ConcreteComponent Component <|.. Decorator Decorator o--> Component : wraps Decorator <|-- BorderDecorator Decorator <|-- ScrollDecorator Decorator <|-- ShadowDecorator Client ..> Component : uses style Component fill:#e8f5e9,stroke:#388e3c,stroke-width:2px style ConcreteComponent fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style Decorator fill:#fff3e0,stroke:#f57c00,stroke-width:2px style BorderDecorator fill:#fce4ec,stroke:#c2185b,stroke-width:1px style ScrollDecorator fill:#fce4ec,stroke:#c2185b,stroke-width:1px style ShadowDecorator fill:#fce4ec,stroke:#c2185b,stroke-width:1px style Client fill:#f5f5f5,stroke:#616161,stroke-width:1px

交互演示

动态添加功能装饰
Base
添加装饰
📄
点击左侧添加基础组件

生活类比

装饰器就像是穿衣服或给咖啡加配料

穿衣服

你穿上T恤,再穿上衬衫,再穿上外套。每层衣服都给你添加了新的功能(保暖、正式外观等)。你可以自由组合不同的衣物,而不需要改变自己的身体。

咖啡配料

点一杯基础咖啡,可以添加牛奶、糖、奶油、焦糖等配料。每种配料都装饰了咖啡,增加了新的口味和功能,而不需要创建无数种咖啡子类。

披萨配料

基础披萨可以添加各种配料:芝士、蘑菇、香肠、橄榄等。每种配料都是一层装饰,可以自由组合出无数种披萨。

代码实现

Example.java

实际应用

Java I/O 类库

Java I/O 类库是装饰器模式的经典应用。InputStream/OutputStream 是 Component,FileInputStream/FileOutputStream 是 ConcreteComponent,BufferedInputStream/DataInputStream/ObjectInputStream 等是 Decorator。

Example.java

Python @decorator 语法

Python 的 @decorator 语法糖是装饰器模式的语言级支持,广泛用于日志记录、性能监控、权限检查、缓存等场景。

Example.java

JavaScript/TypeScript 高阶组件 (HOC)

React 中的高阶组件是装饰器模式在前端开发中的应用,用于复用组件逻辑。

Example.java

Spring 事务管理

Spring 框架使用装饰器模式(代理模式)实现声明式事务管理,通过 @Transactional 注解为方法添加事务控制。

Example.java

练习

1

装饰器模式的主要目的是什么?

2

以下哪个不是装饰器模式的优点?

3

装饰器模式中的装饰器和被装饰对象必须实现相同的接口

4

Java I/O 流使用了什么设计模式?