I've been working with MVC for a while now and it's generally a great idea. I first got acquainted with it when starting to work on the BeWelcome code (have a look at http://www.bevolunteer.org/trac/ if you're interested in an open source hospitality exchange project). After that I used it in personal frameworks, based on what I'd seen in BeWelcome and reading from articles like How to use Model-View-Controller (MVC) by Steve Burbeck. My first frameworks were, as one might expect, not providing a whole lot of usability and code reuse. As a colleague of mine said, after having had a look at the code: there were a lot of design patterns present but they didn't seem to be doing much in my code.
After that, I've worked with the MVC pattern in a number of sites as part of my job at Aardvark Media as well as more mature versions of my framework, and it's let me to some personal opinions on the pattern.
- The main point of the MVC pattern seems to me to be modularising the code. The reason it's called MVC is that you're dealing with Model, View and Controller - it's a triad of connections. In order to get the maximum decoupling, this triad needs to be able to work on it's own, i.e. you need to be able to rip out an MVC triad without having the entire code break down.
- Most of the uses of MVC that I have seen means coupling the model of the MVC with other classes. The reason for this is simple: the models provide data access and lots of places can need access to data that doesn't appear in the MVC they're in. From my point of view this poses a problem, though, because it means you can no longer switch out MVC triads as you please.
- The MVC design works best, in my opinion, when all access to the MVC happens through the controller. In web apps, this means running the framework and then picking an MVC triad to run and then be done with it (possibly running several MVCs but running them independently of each other). It's also possible to have MVCs use each, but still using only the controller as the entry point to the code. This ensures exposing methods in just one place.
- This leads to the obvious question: how to avoid code duplication and get proper code reuse, if models shouldn't be shared among MVCs? My personal answer to this is data objects, based on the ORM pattern. The idea here is that the model in an MVC will normally contain general code that does general data lookup and is used by many places (your typical load user code, for instance). The model will also contain some specific code only used by the MVC it is placed in. If the general code is refactored out into a smaller object, that only contains general code, it's possible to make some very flexible data objects based on the ORM pattern that at the same time fulfill all the data access needs of the project.
- This leads to architechture along the following lines: 1) MVCs that do the work of applications and 2) data objects that do the majority of the data grunt work. Data objects are shared among all MVCs - because they only hold generic methods and data, they don't overexpose methods or properties. MVC models only expose methods to the MVC they're in, so there won't be any tight coupling between individual MVCs.
- This means MVCs become more like modules - you can swap them in and out as you please, turn them on or off during debugging, etc.
Switching to a style like this is not very hard. You can go about it piecemeal: first setup a base class for the data objects with some generic features for getting data out of the DB, then setup some object classes mirroring the DB setup. At first, all you want is just an empty child class of the data object class: just enough detail to tie it with the DB table but no more. Test that you can get data out of the proper table and when this works, you can start refactoring models to use the data object instead: instantiate the data object in the model and move the generic data functions into that instead. And ... you're done :)