结构型 困难

享元模式

Flyweight Pattern

运用共享技术有效地支持大量细粒度的对象。

概述

享元模式是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。

适用场景

  • 当需要创建大量相似对象时
  • 当对象的大部分状态都可以变为外部状态时
  • 当需要缓存对象以节省内存时
  • 当对象的内部状态可以被多个实例共享时

优点

  • +如果程序中有很多相似对象,可以节省大量内存
  • +可以提取对象的外部状态,在运行时动态传递
  • +减少对象创建的开销,提高性能
  • +集中管理共享对象,便于维护和统计

缺点

  • 可能需要牺牲执行速度来换取内存
  • 代码会变得更加复杂
  • 需要仔细区分内部状态和外部状态
  • 线程安全问题需要考虑(共享对象的并发访问)

结构

classDiagram class Flyweight { <<interface>> +operation(extrinsicState) } class ConcreteFlyweight { -intrinsicState +operation(extrinsicState) } class UnsharedConcreteFlyweight { -allState +operation(extrinsicState) } class FlyweightFactory { -flyweights: Map +getFlyweight(key) Flyweight +getFlyweightCount() int } class Client { +main() } Flyweight <|.. ConcreteFlyweight Flyweight <|.. UnsharedConcreteFlyweight FlyweightFactory o--> Flyweight : manages Client ..> FlyweightFactory : uses Client ..> Flyweight : uses style Flyweight fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style ConcreteFlyweight fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style FlyweightFactory fill:#fff3e0,stroke:#f57c00,stroke-width:2px style Client fill:#f5f5f5,stroke:#616161,stroke-width:1px

交互演示

共享细粒度对象,节省内存
FlyweightFactory共享池
已共享: 0 个
创建对象
Canvas
享元对象:0 个
渲染实例:0 个
节省内存:100%

生活类比

享元模式就像是现实世界中的共享资源

围棋

围棋有361个位置,但只需要黑白两种棋子。棋子的位置是外部状态,颜色是内部状态。

图书馆书籍

图书馆中同一本书有多个副本,但所有副本共享相同的书名、作者、ISBN等内部状态,而借阅者是外部状态。

文字处理器

文字处理器中的字体对象,每个字符的字体样式是内部状态(可共享),而字符位置和内容是外部状态。

代码实现

Example.java

实际应用

Java String Pool

Java 的字符串常量池是享元模式的典型应用。相同的字符串字面量会被复用,节省内存。

Example.java

数据库连接池

数据库连接池使用享元模式管理数据库连接,复用连接对象以减少创建开销。

Example.java

游戏开发中的粒子系统

游戏中的粒子效果(如火焰、烟雾)使用享元模式共享粒子的纹理和属性数据。

Example.java

练习

1

享元模式的主要目的是什么?

2

在享元模式中,以下哪项属于内部状态(Intrinsic State)?

3

享元工厂(FlyweightFactory)负责创建和管理享元对象