Flyweight(享元)–对象结构型模式
一、意图
运行共享技术有效地支持大量细粒度的对象。
二、动机
1.在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。
2.如果在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?
三、适用性
Flyweight模式的有效性很大程序上取决于如何使用它以及在何处处理它。
1.一个应用程序使用了大量的对象。
2.完全由于使用大量的对象,造成很大的存储开销。
3.对象的大多数状态都可变为外部状态。
4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5.应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
四、结构
下面的对象图说明了如果共享flyweight。
五、效果
使用Flyweight模式时,传输、查找和/或计算外部状态都会产生运行时的开销,尤其当flyweight原先被存储为内部状态时。然而,空间上的节省抵消了这些开销。共享的flyweight越多,空间节省也就越大。
六、实现
1.删除外部状态。
2.管理共享对象。
七、要点总结
1.面向对象很好地解决了抽象的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
2.Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要主要对象状态的处理。
3.对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。
八、相关模式
Flyweight模式通常和Component模式结合起来,用共享叶结点的有向无环图实现一个逻辑上的层次结构。
通常,最好用Flyweight实现State和Strategy对象。
九、举例说明
享元模式像一个对象缓冲池。
本文为李建忠设计模式视频的笔记以及《设计模式-可复用面向对象的软件的基础》和自己的部分见解