Some Thoughts on MVC, Bad Design and Confusion

I was reading a post over here about why the ActionStack in Zend Framework is evil. And I agree. I’ve used ActionStack before in a few older ZF sites (where better alternatives weren’t ready or I just didn’t know about them) but now as the framework has progressed there are many better alternatives to get other ‘actions’ to be executed on every request.

That better alternative is to simply not stack actions. One practice that I’ve been bringing into habit over the last year or so with my coding is to keep my controllers thinned out. As Ryan states: Fat Models, Thin Controllers. And as things have rolled out over the last few months, I’ve discovered that is a Good Thing™.

Skinny supermodels beware, your jobs are at risk…

The hardest part of making your models fat would be understanding what the Model really is in ZF’s implementation of MVC. The view is clear, the controller is clear, but what is the model? With a typical MVC the model is supposed to imply business logic, rules, data access and quite literally everything your application needs to do. With a well designed model you’ll very easily have DRY code and hopefully efficient code.

Zend doesn’t enforce a specific model to follow, so as a developer that’s something that you have to decide on.

If you have fat controllers your model may be completely swallowed by the controller itself. If you’re a fat controller designer chances are you’ve got a lot of repetitive code. If your application happens to have database access, and a few classes that extend Zend_Db_Table, chances are the extent of your model is just those classes. Your model will be very thin and, really, in my opinion, quite useless. This is how I started with Zend Framework. And when I was doing this, I was forced to use ActionStack and other strange techniques to get certain things to happen.

As time progressed and I started working on some larger projects, I realized that these fat controllers weren’t going to work very well. I started transitioning to a fat model and lightening the load on my controllers. As part of this transition I started creating classes with useful, reusable methods. Things such as User::getInfo() or Navigation::getGlobalNav() which are pretty self explanitory just by name. These methods would return usable arrays or iterable objects that would be passed directly into the view via the controller. The advantage of returning raw data is that the methods don’t need, or even care, about the view.

Using the above, I could have a controller that’s as simple as this, where the view handles the raw data that gets returned. All the logic is outside, in a nice tidy, fat model: