1、意图
运用共享技术有效的支持大量细粒度的对象。
2、适用性
以下情况使用Flyweight模式
(1)一个应用程序使用了大量的对象
(2)完全由于使用大量的对象,造成很大的存储开销
(3)对象的大多数状态可变化外部状态
(4)如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
(5)应用程序不依赖于对象标识。
3、参与者
(1)Flyweight:描述一个接口,通过这个接口flyweight可以接受并作用于外部状态
(2)ConcreteFlyweight:实现Flyweight接口, 并为内部状态增加存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态是必须是内部的
(3)UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点
(4)FlyweightFactory:创建并管理flyweight对象;确保合理地共享flyweight。当用户请求一个flyweight时,FlyweightFacotry对象提供一个已创建一实例或者创建一个。
(5)Client:维持一个对flyweight的引用 ;计算或存储一个(多个)flyweight的外部状态
4、协作
flyweight执行时所需要的状态必定是内部的或外部的。内部状态存储于ConcreteFlyweight对象之中,而外部对象则由Client对象存储或计算。当用户调用 flyweight对象的操作时,将该状态传递给它
用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,这可以保证对它们适当的进行共享。
5、效果
使用flyweight模式时,传输、查找、计算外部状态都 会产生运行时的开销,尤其当flyweight原先被存储为内部状态时。然而,空间上的节省抵消了这些开销。共享的flyweight越多,空间节省就越大。
存储节约由以下几个因素决定:
(1)因为共享,实例总数减少的数目
(2)对象内部状态的平均数目
(3)外部状态是计算的还是存储的
6、相关模式
Flyweight模式通常与Composite模式结合起来,用共享叶结点的有向无环图实现一个逻辑上的层次结构。
通常,最好用Flyweight实现State和Strategy对象