Paul Hammant's Blog: MVC: misunderstood for 37 years
Since August I’ve been helping Gastón I. Silva create a microsite about the MVC Family Tree. It is super cool, you should check it out. My angle is that I love Model View Controller, but I am annoyed at how polluted the definition has become. My former CSO, Martin Fowler, wrote a GUI Architectures article in 2006, but I arrogantly wanted to have another go at something pushing towards a definition.
Martin says in his article: “So don’t take my descriptions as authoritative”. The same applies to me - just another guy weighing in on the misunderstood Model View Controller thing.
Characteristics of MVC
As discussed with Gastón back in August, before he got busy creating the above micro-site:
- Controller classically composes models and views. Either at a conceptual startup stage, or on a just in time basis for parts of the UI.
- Model changes can propagate to view w/o controller logic being invoked.
- View changes can propagate to model w/o controller logic being invoked.
- Controller can optionally mediate between Model and View
- View interactions often invoke controller logic for more complex situations (majority case of the above)
- Model is eminently discardable in order to abandon pending ‘changes’.
- Save of the model is often a deliberate action that propagates the models content to a permanent place (over services, or direct to some form of DB or store).
- Models can be nested or extended (Liskov style)
- Views can be extended, and are nearly always nested
- Unless the model is handed to a view, the view can’t access it. In fact the whole science of MVC screams injection in the dependency-injection style.
Java-ish example snippets
view = new ComboBox(new ComboBoxModel()) view = new MyExtendedComboBox(new ComboBoxModel(myStringArray)) view = new ComboBox(new MySpecialComboBoxModel()) view = new MyExtendedComboBox(new MySpecialComboBoxModel()) view = new ComboBox(new MySpecialComboBoxModel(new MyListOfThings())) mscbm = new MySpecialComboBoxModel(new MyListOfThings()) view = new ComboBox(mscbm).withChangeHandler(someHandlerMethod(mscbm))
Why is this so hard to implement correctly?
Sometimes it’s the technology not the idiom
Microsoft’s IIS (.Net 1.1 through 2) really wanted to be in the mix for web-request invocations. Code-behind was a thing for designed pages, which meant a couple of things:
- you were not going to be able to extend the view
- in unit testing situations you could not instantiate the view yourself, to inject in mocks of things that were not the view. Read Michael Feathers’ Humble Dialog paper.
Front controllers not an indicator
The “Model 2 Controller” ideas promoted by Sun in 1998, became associated with MVC, but it is a bit of a stretch really. Firstly, the model and view can’t casually update each other without a controller being the orchestrator of that (the two propagation criteria above).
Secondly, most implementations garbage collect the model between invocations, which although meeting the stateless goals of modern web development, seem to fly in the face of models being deliberately discarded only when “cancel” button being pressed, or after a “save” action has done it’s thing.
Late to the MVC party
In some cases the technologies makers had a good thing going that was counter to the MVC way. Microsoft, for example, had a huge amount of traction with data-binding. This perhaps started with MS-Access in the 90’s, and was very much in their DNA. I wrote some of the history of that for Gastón. This allowed them, in my opinion, to delay arrival in the land of MVC, because their data-binding paradigm was so successful. And successful for them for multiple generations of technology for over ten years.
Candidates/Recruiters and ‘MVC experience’
Because it also detracts from my love of MVC … When I get CVs/resumes from candidates for developer positions, I sometimes encounter a declaration that they X years MVC experience. They often mean ASP.NET MVC (a Microsoft technology from 2008), not the design pattern from 1978. Super annoying, but maybe only to me.