享元模式 -- Flyweight

2017-04-02 01:04:33   最后更新: 2017-04-02 01:04:33   访问数量:319




想象一下如果我们要制作一个文本编辑器,如果将各个字符和嵌入的表格图形都作为单独的对象,这样的运行开销是非常巨大而难以承受的,但是如果不这样做,又无法实现很多灵活性的要求

 

如上图所示,对于一个包含多行的文本列来说,如果每个字母都建立一个对象,那么将会庞大到无法维护的地步

 

Flyweight 模式就是为了解决细粒度共享对象的,对于那些数量太大而难以用对象表示的概念或实体进行建模,从而实现以较低的代价实现很高的灵活性

 

如上图所示,只需要24个字母对象我们就可以实现所有字符对象的建立,我们仍然可以拥有上文中设计的灵活性,但却将对象的数目限制在一个很小的范围内,如果我们的文本编辑器还需要增加颜色、字体、字符集等多个属性限制,那么,我们只需要建立对应的 flyweight pool 即可,因为颜色、字体、字符集都是有限多个

但是,flyweight 无法实现为每个字符指定不同的颜色或字体,只能实现全文统一的字体、颜色、字符集指定,这也是他的一个限制

 

  1. 程序拥有大量对象,造成了巨大的开销
  2. 所有对象的外部状态可以被去掉,从而实现共享成为多组对象
  3. 程序不依赖于具体对象的标识

 

 

 

如上图所示,Flyweight 通常由以下模块构成:

  • FlyweightFactory -- 用来创建并管理 flyweight 对象,他确保了 flyweight 被合理的共享,用户只能通过他来获取具体的 flyweight,他的 getFlyweight 方法通过从 flyweight pool 中获取现成的 flyweight 或是通过创建新的 flyweight 来实现向 Client 提供可以使用的 flyweight 实现
  • Flyweight -- Flyweight pool 中对象的抽象类
  • ConcreteFlyweight -- Flyweight 的具体实现类,可以被共享的对象,描述了被共享对象的内部属性,每个对象必须独立于具体的使用场景而存在
  • UnsharedFlyweight -- 同样是 Flyweight 的实现类,与 ConcreteFlyweight 不同的是,他是不可以被共享的,Flyweight pool 中也允许存在这样非共享的类对象

 

正如前面所说,Flyweight 模式实现了空间上的共享,很大程度上缩减了存储空间的开销,但是与此同时,对象的传输、查找或计算都会产生运行时的开销,可以说,Flyweight 是一种用计算时间换取存储空间的模式,特别的,如果对象所有状态都是依赖计算而不是依赖存储实现的,那么对象将可以在最大程度上被共享,从而最大程度地节约存储空间,但是这样计算量将会显著上升

另一个问题,是垃圾回收问题,被共享的对象如何计数,什么时候可以被认为可以回收,有时会变得很难判断,当然,如果共享后对象数目并不大,那么这并不是需要考虑的问题

 






读书笔记      技术帖      龙潭书斋      设计模式      共享      factory      design pattern      flyweight      享元模式      享元     


京ICP备15018585号