« O Holy Night (Programmers version) | Main | Corporate Christmas Carols »

May 21, 2008

Model - View - Controller and Decoupling of Components

In the fourth episode of the StackOverflow audiocast, Joel Spolsky asked why the Model – View – Controller (MVC) pattern has become so popular in software design. Thinking about it, I realized that the question ties in with a recent presentation I created called “Secrets of a Software Architect” and, in particular, the “Keep Components Loosely Coupled” principle.

One rough analogy I came up with is internationalization. For the first language, it is easier to just put all your messages inline. But when you want to be able to localize your software for multiple locales, you are better off using an internationalization framework that separates out the text of the messages into separate components. This separation defines a clear interface between the code using the messages, and the messages themselves.

MVC is not just a theoretically clean way of separating out responsibilities: it can make it easier to define clearly defined interfaces between the program logic, data structures, and presentation layer, thereby avoiding implicit couplings, and making it easier to modify each part, be it in isolation or in concert with the other components.

From the point of view of the back-end of a web app, typically the presentation layer will map the output data structures of the program to web pages (HTML + CSS + Javascript). From a front-end web designer’s point of view, the plain, semantic HTML is the underlying data structure, while the CSS rules form the presentation layer that decides how to display your content. (On a side note, Joel mentioned that the order of the content within the HTML file dictates the order of the content when displayed. Technically, it is possible to display the content in a different order than it appears in the source file, but for arbitrary reordering, either assumptions need to be made about the sizes of the various page components, or some Javascript code must be used to resize the components appropriately.)

The first time you write a web app, you might find it easier to just mix it all up together. But when you do want to make a change to, for example, a font size, typically it will cascade to many elements of your output, and it is easier to change in one place than to unwind all the locations in your code producing content that also need to be updated to change any associated inline style rules. From a performance point of view, it is also more efficient to have all your style rules specified in one place, and it will save bandwidth, particularly after the stylesheet is cached. This isn’t a big issue for most people’s web sites that don’t get much traffic, but for a site that plans to scale up to many visitors, it can be important.

A few miscellaneous responses to questions asked by Joel in the audiocast:

  • One objection Joel raised is how a change to a web page’s appearance is often going to require a change to the HTML as well. While this can often be true, since the HTML output is typically generated via a template, both the HTML template and the CSS can be handed off to a designer to be modified.
  • Joel asked if anyone truly implements different skins for a production web site. For my directorate’s web site at work, I did indeed implement multiple styles that the user can select from — it was just easier than trying to argue with each person who proposed something different that the default design (the design was based using specific design principles, but as can be expected, not everyone shares the same views as I do on user interface design).

The Model – View – Controller pattern’s value lies not in supporting skinning, as Joel described in the audiocast, but as an approach to defining clear interfaces between different components, thereby enabling them to be better decoupled. As an added bonus, it can also help separate user interface components from code components, allowing them to be worked on separately.

Posted by Isaac at May 21, 2008 10:15 PM