Model! View! Controller!
The Model/View/Controller paradigm has been around since 1979, when Trygve Reenskaug came up with what is arguably one of the most influential concepts in modern software history. Twenty five years later, it still forms the underpinnings of the vast majority of our user interfaces, and has extended beyond the realm of rich client design to serve as the guiding light for web frameworks that trying to make the painful process of designing complex web applications on top of dumb, stateless communication protocols a little bit less traumatic.
But what is MVC, really? You can’t quite call it a pattern, because it’s more than a simple design precept: it’s really an entire way of thinking, one that emphasizes component isolation in the service of flexibility. This separation of concerns is the key concept that MVC brings to the table.
Specifics, now:
Model: A model is a virtual representation of some external entity. Ideally, it’s fully encapsulated — which is to say, it implements nothing more and nothing less than the important aspects of its real-world analog. It is completely and monomaniacally self-obsessed.
View: The visual representation of your system. This is what users see when they look at their monitors, the tip of your application’s iceberg. More to the point, it presents the contents of the model, and does so without knowing very much at all about the details of that model’s implementation.
Controller: So far, we’ve described two largely inert components: a model that’s pretty much satisfied with just hanging out and being itself, and a view that mostly just cares about preening for users and strutting its stuff. Something has to serve as the motive force in this closed little world, and that’s where the controller comes in. It’s the one that reacts to external events, performs whatever business logic is necessary, and updates the model (and possibly the view) with the results.
This may seem like a lot of trouble to go through for a simple UI, but the division of labor inherent in this approach, and the opportunities for loose coupling that it affords you, are really quite important. In the bad old days, when interactive program design was just a barely evolved slug-creature pulling itself out of the protoplasmic muck of creation, all of these components were munged together into one unseemly undifferentiated blob. Which meant that every time you wanted to change some aspect of the program’s UI, you’d probably have to get the model involved, whether or not it really needed to be; and vice versa. Everything was tightly coupled, and the parts of the system that should have been stable were inextricably linked to the parts that weren’t. Nothing was safe.
Things have steadily improved since those dark days. In some sense, you could say that the history of software design has been an ever more desperate effort to isolate volatility.
Let’s think about this in different terms. Imagine a movie theater. If you were to recast its essential components in the light of MVC, then the view would be the screen, the model would be the movie reel, and the controller would be the projector. The beauty of this arrangement is that you can take any movie and drop it into any projector and display it on any screen. It’s a simple question of shuffling around compatible, but loosely-coupled, components,
Now what if these components were combined? What if a movie theater was a single monolithic entity, in which the movie, the projector, and the screen were all shipped as one package. Whenever a new movie came out, someone would have to build a new theater, install the movie/projector/screen, and show it. When they wanted to show a different movie, they could either (a) tear down the theater and build a new one or (b) hire a team of contractors to come in with drills and hacksaws and sledgehammers and remove the old movie and install a new one, hoping that the new reel would work with the old projector. Probably it wouldn’t: you’d need major modifications to the hardware, which would likely require modifications to the screen, and so on.
So separation of concerns is a good thing. That’s fairly obvious, I think. But once you get down to actually trying to implement this stuff, things get a lot muddier.
More on that later.
2 Comments