PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1
CHAPTER 13 ■ DATABASE PATTERNS

always have that kind of control over the situation. The same object may be referenced at several
different times within a single request. If you alter one version of it and save that to the database, can
you be sure that another version of the object (perhaps stored already in a Collection object) won’t be
written over your changes?
Not only are duplicate objects risky in a system, they also represent a considerable overhead. Some
popular objects could be loaded three or four times in a process, with all but one of these trips to the
database entirely redundant.
Fortunately, fixing this problem is relatively straightforward.


Implementation


An identity map is simply an object whose task it is to keep track of all the objects in a system, and
thereby help to ensure that nothing that should be one object becomes two.
In fact, the Identity Map itself does not prevent this from happening in any active way. Its role is to
manage information about objects. Here is a simple Identity Map:


namespace woo\domain;
//...


class ObjectWatcher {
private $all = array();
private static $instance;


private function __construct() { }


static function instance() {
if (! self::$instance ) {
self::$instance = new ObjectWatcher();
}
return self::$instance;
}


function globalKey( DomainObject $obj ) {
$key = get_class( $obj ).".".$obj->getId();
return $key;
}


static function add( DomainObject $obj ) {
$inst = self::instance();
$inst->all[$inst->globalKey( $obj )] = $obj;
}


static function exists( $classname, $id ) {
$inst = self::instance();
$key = "$classname.$id";
if ( isset( $inst->all[$key] ) ) {
return $inst->all[$key];
}
return null;
}
}


Figure 13–5 shows how an Identity Map object might integrate with other classes you have seen.
Free download pdf