No, really. What web developers thought of in the noughties as being MVC doesn't scale.

May 16, 2014 11:01 PM

I haven't seen the F8 session or used Flux. I've just vaguely skimmed some of the reddit comments. However…

Once upon a time, there was this thing called the Model View Controller architecture. It was a product of the Smalltalk community, but then so were Design Patterns and Extreme Programming. At its heart, it was the simple idea that Model classes should be responsible for representing the state of your application, View classes should be responsible for drawing your user interfaces and presenting that state to your users, and Controller classes should be for translating actions performed by your user into changes to your model, that were then reflected in your view.

In a typical screen for an MVC GUI you might have any number of widgets, each drawn by their own independent view objects, backed by different models, connected to multiple controllers. Almost forty years after the MVC pattern was formulated for GUI development it is still out there, albeit in obscure rarely-used frameworks like Cocoa Touch.

Then, twenty years after MVC was introduced to the Smalltalk world, along came the Model 2 Web Application. In an attempt to make Java web development fit into the growing J2EE spec, the Java community seized on MVC and mapped it almost arbitrarily to the web. Every HTTP request would be served by a single controller (servlet), which would collaborate with zero-to-many models (EJBs), and map the resulting data into a DTO (Pay no attention to the man behind the curtain!) that could be passed via RequestDispatcher to a single JSP view.

The sleight-of-hand was the assumption—baked into the servlet spec—that each HTTP request would map to a single controller which would delegate to a single view. A few frameworks like Tapestry tried to buck the trend, but a Java developer years later could literally replace servlets with actions, EJBs with dependency-injected beans and JSPs with the templating language du jour, and still deliver a not-unreasonable technology choice in most circles. This malaise even infected other undeserving languages like Ruby.

The problem is that even in a very simple web application, a single page contains elements that by rights should be the responsibility of different views, backed by different controllers and their own models. The single controller-per-request, or even the primary controller-per-request is a broken paradigm, and one that every developer has come up with some sub-optimal tower of contraptions to compensate for.

As a result, your average non-trivial Java web application ended up being a mess of controller implementation inheritence, servlet filters, interceptor stacks, view decorators and arbitrary objects placed in the template engine's context to allow the drawing of all the bits of the web page that don't belong to the increasingly impure controller.

Amusingly, the "Type 2" approach to web MVC isn't a bad fit for REST-based systems, (because a REST resource usually does have a single responsibility), but most pure REST systems figure it's overkill… because a REST resource just has a single responsibility.

A simple inversion fixes so much. Going back to the GUI paradigm and flipping the process around so the view comes first and then delegates to controllers and models as necessary is already the go-to strategy for single-page applications and frameworks like Backbone. This kind of "view first" is also a perfectly good strategy for server-side page generation, one that large distributed systems have been taking advantage of for years to delegate fragments of page generation to independent external services.

This blog post was brought to you by the Society for Sending Charles Back In Time Fourteen Years To Slap Himself.

Previously: Now Hiring: Enterprise Senior Support Engineer

Next: Curbing Online Abuse Isn't Impossible