The Model Layer of the MVC triad: I’ve been thinking this over for the past few months since using the Doctrine ORM and I think I’ve finally made some progress to get this issue licked. In the past, I’ve agonised over this issue and blogged about my progress. Some weeks or days later I tried to probe the community on what they would do, Now I think I’d have an idea on what I would do.
After some more thought and lots of research on the subject, I’ve come to a solid point where I actually have something to try out which seems semantic aside from the naming of the class (Service Class) – but this is derived from what some people are talking about in ZF circles starting from Matthew Weier O’Phinney who was coining it as the “Gateway to the Domain” from early on, then later changing it to “Service Class”.
The Service Class
So this is what I chose to go with: For each model class, I’ve got a Database Agnostic Service class - in fact, it uses the Entities Produced by Doctrine ORM to talk to the database, but isn’t entirely reliant upon Doctrine to Provide the Model Layer on it’s own. Using Doctrine as your Model Layer alone I suppose is better than extending Zend_Db which is highly discouraged by everyone, but you still have the database dependency.
I thought well, I’ve done a lot of feeling around the subject, maybe I’ll just ask around. So over to twitter I go. I sent Matthew Weier O’Phinney a tweet asking if it is right that Doctrine models are relatively empty whilst Model services are filled with business logic and he answered: “Absolutely. Plain old PHP is perfect for entities.” but I had no idea WTF that meant.
The Service Layer uses the Model which is the Entity. My further attempt to clarify the situation and continue discussion didn’t get a response – maybe because I had to condense words and use accronymns to fit the message in or he had just become too busy. So on my own I go again.
After mulling over it a few, I thought I’d just run with what I’ve got. It seems to be semantic, but it has a lot of responsibilities:
- The Model Service Class is a Resource.
- The Model Service uses the ACL layer to check if a Role Identified has the Privileges to make it’s request prior to usage.
- The Model Service creates Entities by using its Model Factory/Finder methods such as FindById it then returns either an array or an Entity based on what Hydration mode was specified (default is array).
- The Model Service creates Forms and uses it for Validation
- The Model Service provides the CRUD methods so that the Controller does not have to worry about instantiating and configuring models to Create Update or Delete data.
- The Model Service uses Zend_Cache and can use caching on non-changing data such as lookup lists status or types and large collections of data used in drop downs, lists or datagrids.
- Although there is no factory for it, the Model Service can create and use other Model Service classes.
The Service Layer is not passed to the View either. The View is configured by the Controller and has data shoved into properties/member variables.
- The Service Object can be passed to the View if required, so that the View can use the Sevice object to interrogate models on it’s own. We trust that those writing the View Markup will only be using the service object _strictly for reading only_.
I’ve been working with this setup for a few weeks now. This method is very testable and makes for an extremely thin Controller Layer.
What do you guys think?
Have we over engineered this thing? Should it be called the Service Layer as more and more people are coining it as? What suggestions can you make to make this better?
- Zend Framework Model – Research into Possible Domain Model Solutions
- How would you handle this? – Service Layer slowly getting polluted (or so it seems)!
- Started Draft Post on Zend Framework, Doctrine & PHPUnit Setup
- Test Results on Memory Usage of Zend Framework and Doctrine with APC
- Our New PHP 5 Framework Cubix developed to 2.1