享元模式
享元模式允许在对象之间共享相同的状态,从而减少内存占用。享元模式的核心思想是将对象的状态分为内部状态和外部状态,其中内部状态是可以共享的,而外部状态是不可共享的。
备注
简而言之,享元模式就是将多个对象间共享的状态提取出来并封装到一个新的对象中,而原始对象则包含对这个新对象的引用,从而实现状态复用。
结构
享元模式示意图
享元模式中,FlyweightFactory
用于创建和管理享元对象,通过维护一个享元对象的缓存池来实现创建、维护和共享。Flyweight
是享元对象的接口,维护内部状态;Context
是上下文,代表内部状态和外部状态的组合。
示例
如果要类比的话,枚举类型就是享元模式的一种实现。枚举类型类似于提前定义了一系列状态对象,而枚举类型本身则是享元工厂,通过枚举值来获取对应的状态对象。
备注
对享元对象的操作可以定义在享元对象内部,也可以定义在上下文中。
应用场景
- 仅当对象的多个实例之间存在共享状态时
优缺点
优点
- 可以节省大量内存
缺点
- 引入了共享状态,可能会导致并发安全问题
- 牺牲执行速度来换取内存
- 代码变得不直观
代码示例
下面的代码示例展示了一个使用享元模式的 Python 示例。在这个例子中,我们要在森林里画很多树。每棵树都有一些内部状态(name
, color
, texture
,这些是可以共享的)和外部状态(x
, y
坐标,每棵树都不同)。
TreeType
类是享元对象,它存储了树的内部状态。TreeFactory
是享元工厂,它确保具有相同内部状态的 TreeType
对象只被创建一次并被共享。Tree
类是上下文对象,它包含了外部状态(坐标)以及对一个 TreeType
享元对象的引用。
客户端代码(Forest
)通过工厂获取享元对象来创建树,从而大大减少了内存占用,因为许多树可以共享同一个 TreeType
对象。