ModelViewController

ThoughtStorms Wiki

Read with : (DCIArchitecture)

The sad story of Model View Controller

MVC is the first acknowledged pattern. And must surely be one of the most widely misunderstood, and argued about patterns in the cannon.

MVC was invented as part of SmallTalk, and in its original form makes sense in that environment.

Here's the paradigm case. Imagine you need to write a program which stores a table of several columns of numbers and draws different graphs and charts based on them.

The initial division is simple :

  • the model contains objects representing the table of numbers
  • the view objects will draw the graphs
  • and the controller will include the drop down menus for choosing which graphs to draw, and possibly some inputs of axis labels,

The important point to note is that this is a separation of dependency for the benefit of programmers. The model can be written, executed and tested independently of the view and controller. The model and view are similarly independent of the controller. Although co-ordination is required between the levels, the dependencies are only one-way. So only higher level has to worry about co-ordination with the lower. This simplifies and cheapens the cost of co-ordination of writing the code. (See also OneWayLinks)

But we should be aware that much of its brilliant simplicity depends on the context of the Smalltalk environment.

First, because Smalltalk is a self contained environment with its own virtual machine and with certain standard tools, it makes sense to say that we can write the model independently of view and controller. In particular Smalltalk has a general purpose inspector for looking inside any object, and a command line terminal from which the model can be created and set in motion.

Most other languages and environments fall short of this ideal situation in some ways. It may be possible to write a test harness and unit tests (Wiki:UnitTest) for the model objects, but these require extra coding. You will have to write your own inspection methods, even if they're simple print statements to standard output. You probably don't have a command line interface to the running virtual machine so you can't interactively talk to the objects you've created, to manually test them or just poke them a bit and see what happens.

Second, MVC principles defined the Smalltalk GUI. Not all Window systems work this way. In some, you're encouraged to attach mouse-sensitivity (controller) to visual objects. The windowing system has saved you a lot of effort, but has already wired together view and controller in a specific way which is different from MVC as originally conceived.

A related point. Smalltalk objects have a publish and subscribe way of communicating where they can broadcast a "changed" message to any object which chooses to listen to them. This means that the model can drive the view while knowing nothing about it. And the view can co-ordinate with the model, simply by listening for it's "changed" signal. For example we could replace our table of numbers with some kind of dynamic process (model or live feed). The model objects would broadcast every time they changed, and the listening graphing panel would automatically update itself. In other GUI systems, without broadcast, this would have to be achieved with callbacks, that require tighter co-ordination between model and view.

These problems come together when we consider attempts to map MVC onto http based web services. The form of http (self contained calls to a stateless server, most of which start on a page, and all of which expect a returned document - page or xml token) is very different. You can try to build MVC on top of http, but there's an ugly mismatch.

Deciding what in MVC maps to what in http is hard. And no mappings are exact. If we think pages are views and http requests are controls, we find there's no sensible meaning to being able to run and test the view independently of the controller. And indeed, many presentations of MVC in this context show two way dependency and co-ordination costs between V and C. There is also, existing within the standard web world, an alternative pattern (raw data and template) which is right for web-work, but doesn't exist in MVC.

Another problem with MVC is this. It was designed as a pattern for fairly small scale GUI work on a personal computer. When trying to move it into the enterprise computing world it often gets conflated with another 3 layer pattern. One which consists of Web server, Control (Business) Logic, and Database.

These are actually two very different patterns. MVC is a one-way separation of dependency to make programmers' lives easier. Whereas webserver, business logic, database (WBD) is a two-way separation of activity which helps in the administration and distribution of a system. It allows us to separate the three layers onto different machines, or to easily replace one layer with a functionally equivalent alternative. (More on ThreeTierArchitecture)

Model-View-Controller Webserver-Business Logic-Database
Model is a self-contained picture of the realm of data and it's causal interactions. It's potentially active. The datamodel is a passive store of data about the realm (A database or set of beans with getters and setters)
The Controller is the highest level, and the most superficial or inessential part of the program. The controller is equivalent to the good old fashioned idea of control logic and includes the business logic and knowledge. It's the middle layer, and essential to the system.

Although separation of dependency is theoretically possible with WBD it is often not very meaningful to try to observe what a system is doing without having all three layers working at once. And although ensuring the plugability of each layer is possible in MVC, it isn't a requirement of the pattern, and is often overkill.

Another problem with MVC, which can be illustrated with our original example, is that not everything fits it. For example, suppose we want to suppliment our original program with some sort of smoothing and normalizing functions. Where does this extra processing belong?

We can have three equally compelling intuitions :

  • if we think that the controller is like control logic, ie. it's the things that are done to the data, then we can see that processing the data to produce these smoothed series belongs in the controller.
  • or we may think that as there is nothing new in this data, it's just a particular way of looking at it, it's a view.
  • or we may think that because these summaries are equally in the domain world of the data, they are rightfully part of the model.

Depending on other circumstances, any of these might be the most appropriate.

Another intuition might be that this functionality itself should be distributed through the three levels. This leads to an AntiPattern I call "too much code, too many pieces" (Wiki:RavioliCode). A smallish task has been separated into too many, unmanageable, fiddly fragments. (A GranularityMistake. Though contrast general principles of MicroValue)

Conclusion

I'm not trying to bury MVC. It's a good and useful pattern.

But it's not the final word in UI design. And it's not always appropriate for the environment or scale of your problem.

Many design disasters (Struts/MVC model 2) are committed in the name of MVC. We should learn to assess its relevance critically. Remember that the Smalltalk community themselves have long since replaced it with a tighter coupling of model view and controller called Morphic (SqueakLanguage) that's not dissimilar to the way Visual Basic, Swing or most GUI libraries actually work. View and Controller are encapsulated in the same object.

On the web, over http, I'd suggest thinking seriously about three emerging WebServiceDesignPatterns rather than assuming MVC is right.

See also : Struts/FirstImpression for the first draft of this essay (an email I sent to my colleagues on first reading about Struts)

Alternative Views

If you aren't convinced MVC is wrong for web-sites, Manageability lists 5 rules for TemplatingEngines : from http://www.manageability.org/blog/stuff/5-rules-of-model-view-separation from http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf

BillSeitz:ModelViewController links to which http://diveintomark.org/archives/2001/12/19/modelviewcontroller which is OK, but re-iterating the party line

MVC seems to be fragmenting into more and more different things, especially on the web : http://welcome.totheinter.net/2008/08/05/mvc-pattern-for-the-web/

See UncleBob discussion