In the last few weeks I’ve been thinking about models allot. Models, as in Model-View-Controller modules,
are the most abstract and hard to frame-out part of this holy trinity (one might say Models are the “Holy
Spirit” of MVC). So what’s the best practice here, if there is even one?
Models represent data and provide the means to preform data-specific actions. In a sense this is exactly
what objects are (as in OOP objects) - so one might say that simple container objects are in a sense what
the model should be. But in the real world, you almost always need data persistence, which means having
some kind of storage mechanism to read from or write to. In the PHP world that’s almost always a database
(and almost always MySQL) but it doesn’t have to be: Models could be based on RSS feeds, XML or other
serialized data formats, web services, and more. In fact, $_SESSION could (and should?) be a part of your
model. So data-layer abstraction could be a nice thing!
It gets even further - think about a model class which uses several data layers, mixing RSS feeds with
locally stored meta-data for example; Or a Transaction class, that when saved, will both
save local information in the DB and send an API call to PayPal, executing the transaction or fetching
information from PayPal’s logs.
Well - getting back to my point, I was thinking about the best way to “frame-out” models and I have to
say I didn’t come up with a good, practical solution. One of the conclusions I did made however, is that
we are thinking completely wrong when designing our models. We (or at least I) have a tendency to design
the model layer by starting from the storage and data access layers (the DB schema usually) and then
going to the application layer. If you ever used Propel, it
does exactly the same (as all ORM attempts probably do) - you design a database schema, and then build
your model classes around it. Then, whenever your application requires some complex relations or data
access, it becomes hell and you need to hack things together to make it work (try things like efficient
batch updates, or efficient JOINs).
This is obviously wrong. We should be building or at least designing our application first - designing
the logic, planning what sort data and what data related actions each action will need to perform, and
then design model classes accordingly. These classes in turn will be used to design the data storage
layer. The end result will probably be a set of classes for each DB table (or pseudo JOINed tables for
that matter) but in run time, will be much more efficient and easy to use.
I am not sure how this can be done and even if this is possible - consider it to be a theoretical idea.
But think of the possibilities when you start from the application layer and go down - instead of being
limited by your data access layer.
You’re more than welcome to share any thoughts (or objections).