Caching For Fun And Profit
Many developers start out by caching objects in the session, and caching random array data in memcached. So why not cache objects in memcached?
Going further, why not cache every object in memcached? Thus, objects could persist and be shared across requests. If an requested object existed in the cache, that object’s database queries could be avoided altogether.
The ObjectFactory class performs the above. You can read about its usage below. A couple more notes about it.
- Just as we serialize objects stored in the session, we need to serialize objects stored
in the cache. We use__autoloadto unserialize objects when they are retrieved. - In order to minimize cache operations, the class uses a local cache (an array) that
persists for the lifetime of the page request. Only at the end of the request, the local
cache is persisted to in-memory cache in the class destructor. (This idea borrowed from
the Wordpress Object Cache.)
Caching
The system was designed with a caching layer built in. Here is a (very) rough diagram of the system layers.
| View → Controller → Model (Business Logic) → Object Factory → Business Objects → DB |
What this means is that when a new object is created, it is stored in cache. For example, if you view a browse page of 10 items, 10 new objects are created and cached. Then, if you click on an item to see its detail, the same physical object in memory is used on the detail page. This can drastically cut down on the database access, as objects can be retrieved without the database at all in a cache hit.
Usage:
- Never use new to instantiate a class
- Use the factory to get a class instance, for example:
$obj = Zend_Registry::get('factory')->get('classname');
Features:
- Checks the object cache and return the object if it exists
- Otherwise, create a new object of the class and cache it.
- Handles thread concurrency issues and lock contention
Future work:
- Messaging and communication among objects handled with Observers/Observeables pattern a.k.a. message bus.