Model-View-Controller and the Web

I was thinking a lot Friday about the Model-View-Contoller paradigm (aka Model 2) and how it applies to web application design. I was having conceptual issues which I suspected were largely a result of not really understanding the MVC pattern. So I’m trying to sort this stuff out.

In writing this, I ran across Andy Wardley’s article, “MVC: No Silver Bullet“, which shaped my thinking a bit.

The main heartburn that I have with MVC for web applications is the thought that actions are always directed by the Controller, when in fact, often it’s the View that’s getting the clicks. As I was building an MVC framework for my web apps, the Controller was mainly just dispatches to the Views – which doesn’t seem to fit the available documentation on how MVC is supposed to work. If the View prepares the forms, isn’t it the View that should know how to process the form submission?

The answer, according to what I think is the seminal paper on MVC, is this: “Each view is associated with a unique controller and vice versa.” This leads me to wonder: if there is a one-to-one mapping between Views and Controllers, why are they distinct at all? In a rich-GUI environment, I suppose separating out the View and the Controller might make some sense; the View knows how to display the Model, and the Controller processes the mouse-clicks and keystrokes. Since these are very conceptually different, they deserve different classes. That said, in a web environment, the only events are HTTP requests – either page-GETs or form-POSTs – and are more intimately related to the underlying pages. For a pure GET, the Controller only has to dispatch to the right View. For a POST, the Controller should theoretically update the Model, and then refresh the View. That said, to me it makes more sense to keep the form generation code and the form processing code in the same module, which means the View. So the Controller, in a web framework, ends up being just a dispatcher.

I think that the Sun definition of “Model 2” is pretty close to this model, and is somewhat divergent from the Smalltalk MVC pattern. (But that’s okay.) Likewise, the flow picture associate with Catalyst, seen below, seems divergent because it puts the controller completely in charge, rather than having that close one-to-one relationship with the views.

Note that I’m not trying to suggest that the View does the real work. Rather, I suggest that the Model does the work, but that the View marshalls the inputs.