I’m regularly thinking about how to represent data in a relational database in OO PHP5 that doesn’t make me walk away feeling like i’ve just created something that smells bad.
The key thing for me is that my code should not care that the data is coming from a relational database. This poses one or two issues.
- In a relational database, data typically has other ‘meta’ data associated with it. Id’s, timestamps and other snippets of information that are not strictly part of what my object is trying to represent.
- If my object is not aware of how it should serialise itself, who is?
This of course isn’t a new problem. My language of choice (currently PHP5) has many ORM libraries available to it – Doctrine, Propel and more – most (or all) of which are loosely based around the Active Record design pattern.
My only problem with these frameworks is that they seem to do too much ‘magic’ for me (and I like to retain at least some control over what’s happening between my app and the database). Of course, it could also be that I have either not invested enough time in learning to use one of them to it’s maximum potential.
Despite that, the Active Record pattern appears to be quite a satisfactory way of creating that link between my application, and how it’s storing it’s data. My core objects can exist how I want them to, and their ‘datastore’ can be represented by an active record object (who’s attributes are exactly the same as the columns in the database) on the class itself. It gives me the degree of separation that i’ve been looking for.
However there’s still a piece missing. My core class still has to contain the relevant logic to load it’s associated active record. This suggests some static factory methods (I refer to my earlier comment on things that smell bad!), so i’m going to create a ‘Builder’ for my core object that’s concerned with marrying up the active record with the core object itself. Here’s how it looks (simplified) in a class diagram.
I’ve not closed the doors on Doctrine or Propel though, so it’ll be interesting so see just what an established ORM framework like Doctrine can do for me on top of this basic implementation.