本文首发于 http://www.YoungZY.com/
原文网址:Object Pool Pattern
意图
对象池对性能有显著的提升。在以下场景中最有效:实例化过程复杂的对象;实例化频率高的对象;同一时刻用到的实例数量较少。
问题
对象池(也叫资源池)是用来管理对象缓存的。一个使用了对象池的客户端可以请求对象池中已经存在的实例,而不用自己创建。一般来说,这个对象池是可以自动增长的,当它是空的时候可以自己创建对象。或者我们可以限定对象池的大小。
将所有可重复使用的、当前未使用的对象放在同一个对象池中以保证其连贯性是有必要的。为了达到这个目的,对象池应该是单例的。
讨论
对象池允许其他程序从中获取对象,当用完后在放回池中,以便下次再用。
但是我们不会一直等着某个对象被释放,所以在必要的时候对象池可以创建新的对象,但一定要有定期清理未使用的对象的机制。
结构
对象池的基本概念就是如果某个对象的实例可被重用,那就重复使用,而不是不断地创建新的实例。
- 可重复使用对象:在某一场景会被使用,之后该场景不会再用到的对象实例
- 使用者:可重复对象的使用者
- 对象池:为使用者管理可重复使用对象的
通常,最好将当前未使用的所有的”可重复使用对象”保存在同一个对象池中,以便有个一致的策略来管理它们。所以,”对象池”对象被设计成来单例。它的构造函数是私有的,为了让其他类调用它的 getInstance
方法去获得一个唯一实例。
当“使用者”需要一个“可重复使用对象”的时候,调用“对象池”的 acquireReusable
方法。“对象池”维护着一个“可重复使用对象”的集合,利用这个集合存放当前未被使用的对象。
当acquireReusable
方法被调用时,如果池中有对象,就会返回一个对象并将其从可用池中移除;如果池是空的,并且可以创建新的对象,就会创建并返回;如果不能创建新的,就会等正在使用的对象释放。
当“调用者”使用完“可重复使用对象”后就会调用 releaseReusable
方法,该方法会把用完的“可重复使用对象”还给“对象池”。
在对象池模式大部分的应用中,控制“可重复使用对象”的总数是合理的。这样,对象池就不会创建多余指定数量的实例。所以需要一个方法来控制新建实例的最大数值。就像上图所示的 setZMaxPoolSize
方法。
举例
对象池模式跟办公用品仓库类似。有新员工来时,人事主管需要给他准备工作空间。她要检查一下仓库里是否还有空余的设备。如果有,就用;如果没有,就需要采购。如果有员工离职了,他的设备又会被放回仓库,以备下次再用。
核查清单(也可以理解为应用步骤)
- 创建一个包含一组可重复使用对象的对象池
- 给对象池创建“获取”和“释放”的方法
- 确保对象池是单例的
经验法则
- 工厂方法模式可以用来封装对象的创建逻辑,但是在创建之后不会管理它们。对象池模式跟踪它创建的对象。
- 对象池通常用单例来实现。
(译者注:详细的代码实例请移步 GitHub )
加入讨论