意图
运用共享技术有效地支持大量细粒度的对象。
适用性
当以下情况都成立时可以使用享元模式:
- 一个应用程序使用了大量的对象。
- 完全由于使用大量的对象,造成很大的存储开销。
- 对象的大多数状态都可变为外部状态。
- 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
- 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
结构
参与者
Flyweight
——描述一个接口,通过这个接口flyweight可以接受并作用于外部状态。
concreteFlyweight
——实现Flyweight接口,并为内部状态(如果有的话)增加存储空间。
UnsharedConcreteFlyweight
——并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。
FlyweightFactory
——创建并管理flyweight对象。
——确保合理地共享flyweight。
Client
——维持一个队flyweight的引用。
——计算或存储一个(多个)flyweight的外部状态。
协作
- flyweight执行时所需的状态必定是内部或外部的。
- 用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight独享,这可以保证对他们适当地进行共享。
效果
使用Flyweight时,传输、查找和/或计算外部状态都会产生运行时开销,尤其当flyweight原先被存储为内部状态时。然而,空间上的节省抵消了这些开销。共享的flyweight越多,空间节省也就越大。
存储节约由以下几个因素决定:
- 因为共享,实例总数减少的数目。
- 对象内部状态的平均数目。
- 外部状态时计算的还是存储的。
实现
实现Flyweight时,注意以下几点:
1)删除外部状态。
2)管理共享对象。