Identity Map

I find it liberating to have an identity map in place. It is a kind of safety net that allows me to navigate the object graph, retrieve objects and make updates, safe in the knowledge that I am not compromising performance or model integrity.

Factories are the main users of the identity map. Before converting raw data in to an object, they check the data for the existence of an object identifier. If an identifier is present they use DomainWatcher::exists to see if a corresponding object has been loaded already. If there is no such object, the factory goes ahead and creates one, then adds it to the map using DomainWatcher::add.

Mappers are the second most common users of the identity map. Before executing a 'find' for a single object they consult DomainWatcher::exists to see if the object exists already. This avoids unnecessary calls to the database. Secondly, a newly created entity is usually given its identifier at the point where a Mapper inserts it in to the database. In this case, the Mapper adds the new entity to the identity map using DomainWatcher::add.

The domain watcher is a singleton. To avoid cross-contamination between tests, such as unit tests, call the reset method between tests. Other typical problems of singletons, such as unwanted dependencies, can be avoided by accessing the watcher via the service locator, rather than static method calls.