Object pool design pattern
- December 20, 2012
- Posted by: Kamal Rawat
- Category: Design
Have you gone to bowling ? You have to change your shoes before actually get to the bowling arena.
There are lot of shoes in the shoe-shelf, you just need to pick the shoe that fits you, put it on and start playing.
Once you are done, you return the shoes to the shelf, put on your original shoes and leave.
The shoe shelf is a typical real-life example of Object pool (shoes being the object). Imagine if a guy there says, let me first construct the shoes of your number and you have to wait till he prepares the shoes from scratch. Can you afford that long wait?
Same is the motivation for Object pool design pattern.
It uses a set of already created and initialized objects kept ready to use, rather than allocating and destroying them on demand.
The client will: 1. request for an object from the pool, 2. Pool will provide the object to client 3. Client will use that object 4. Client will return the object back to pool (rather than destroying it) 5. Pool can then give the same object to some other client requesting for the object
Since the pooled (already initialized) objects can be obtained in very less (and predictable) time this design can provide a significant boost in performance in the cases where object initialization is taking a lot of time.
Generally the pool will be a growing pool, i.e. the pool itself will create new objects if the pool is empty, or we can have a pool, which restricts the number of objects created.
Normally the reusable pool class (that returns the objects) is a Singleton because otherwise objects will be at multiple places.
The client will get the Reusable object from pool by
Reusable objR = ReusablePool.getInstance().acquireObject();
Note that in case of C++ the return from ReusablePool will be a reference or pointer to Reusable (in case of Java it is any way reference).
The ReusablePool will maintain the collection of Reusable objects and will also keep track of which objects are free and which are already given to clients. The entire maintenance from creation of objects, creating more objects in case of shortage, maintaining the objects (like book keeping) and finally destroying the objects will be done in ReusablePool class.
The Factory Method pattern (or even Abstract Factory pattern in case the Objects are complex) can be used to encapsulate the creation logic for objects. However, it does not manage them after their creation, the management will be all in ReusablePool class.
In languages like Java which has auto garbage collection, using this pattern may be an overkill (esp. in the cases where creation of object is not that expensive).
If the pool is used by multiple threads, it may need the means to prevent parallel threads from grabbing and trying to reuse the same object in parallel. This is not necessary if the pooled objects are immutable or otherwise thread-safe.
One more problem is with bad clients, that acquire the objects but does not release it. The ReusablePool class is responsible for maintenance but it cannot force a client to return the object. Hence it sometimes looks like a violation of OOPs.