tags:

views:

489

answers:

3

Hi, I'm using the data mapper pattern in a PHP app I'm developing and have a question. At present, you request a Site object with a specific ID and the mapper will lookup the row, create an object and return it. However, if you do this again for the same Site you end up with two different objects with identical data. eg.:

$mapper = new Site_Mapper();
$a = $mapper->get(1);
$b = $mapper->get(1);

$a == $b // true
$a === $b // false

So, my question is, should I:

  1. Store instantiated Site objects in the mapper so I can then check if they already exist before creating a new one (could be a problem if there's multiple mappers of the same type)
  2. Do the same as #1 but ensure there is only ever one instances of each mapper
  3. Do the same as #1 but use a static property so multiple instances isn't a problem
  4. Don't worry about it because it's probably not a problem
A: 

I'd go with caching somehow - static mapper classes would be my first choice, and is what I've seen most of. Otherwise, your option 2 (which is the singleton pattern) is probably the best option.

Remember you need to clear this cache when an update is made to avoid returning stale data.

Having said that, unless you are making something to get a lot of use or that does a lot of queries, it may not matter. (your 4)

Also worth looking at for guidance (I'm sure there are many examples, I just know this one best), Propel (http://propel.phpdb.org/) has the caching feature - might be worth looking at how it does it? Or just use it maybe?

benlumley
Thanks for the advice. I think I'll go with option 4 for now and see how it goes. Cheers for the Propel link, I'll probably stick with my own implementation (albeit a bit basic), as I don't really need the advanced features Propel has.
Jack Sleight
Always nice to learn it all yourself as well when you've got the time!
benlumley
+2  A: 

What you're looking for is the Identity Map pattern. Be careful with so called "reading inconsistencies", though. While you use an "old instance", the DB might have been changed already. And while you edit your object, another user might get an instance of it, change it faster and save it faster. Then the other object overrides all these changes again. On the web though maybe not such a big problem since a "page" quickly runs through and no object survives for longer than a few fractional seconds.

openfrog
A: 

I know the question was asked quite a while ago still wanted to answer just in case if someone else runs in a similar dilemma. Actually the above suggestions #1,2,3 that author made are all related and one should consider them all in order to solve the problem.

1) Store each retrieved from DB object in a mapper so that you don't have to do it again when object with the same ID is requested. In all subsequent calls the mapper should return the stored object. This is called IdentityMap pattern. To achieve this make a private property in your mapper to hold an instance of an IdentityMap for a given object type. The Site_Mapper->get() method should always check the IdentityMap for a given ID if the object is not retrieved yet the mapper will go to the database but if it's already stored in the map it returns the cached instance which saves the trip to the database. So then $a === $b should be true because they would be references to the same object instance.

2) Yes ideally there should always be one instance of the given data mapper (Site_Mapper) in order to maintain a single instance of the IdentityMap at a given time. This can be done using Singleton pattern. This is possible with some getter method like Site_Mapper::getInstance() which will always return the same instance of a given mapper. You'd also have to declare the __construct() as a private method to prevent unwanted instantiation using new and make sure getInstance() is the only way to instantiate a mapper.

3) What the author mentioned above about static properties is true as well. To implement a Singleton in PHP one has to use a static property to hold and instance of a Mapper.

I would highly recommend Martin Fowler's book "Patterns of Enterprise Application Architecture" which talks about the above mentioned patterns and many more. It's a good read especially if you're working on your own custom ORM solution. Hope that helps.

Polad Mirzayev