It's Time For NoMVC

Posted: April 27, 2010 In

Comparison of web application frameworks - Wikipedia, the free encyclopediaMVC is a really popular software architecture pattern used on the web. Its become so popular that its too popular. On the Wikipedia comparison of web frameworks it doesn't list the top level architecture for a program. Instead it lists whether MVC is used and if its push or pull. I can't list the number of times I've read or heard a criticism of a program because its not using the MVC pattern. This is turning into a bad thing.

Why MVC Everywhere Is Bad

MVC everywhere is bad for two very important reasons:

  1. There are a lot of programmers and developers who don't know other top level patterns. When its time to use a non-MVC based system they struggle to learn it or try to bend it to MVC which is what they know.
  2. MVC is not always the best pattern. There are a number of different top level patterns and they are good for different cases. Trying to shoe horn everything into MVC is not a healthy approach. Especially when other patterns are better suited.

MVC Is Not Bad

It's not that I am not a fan of MVC. I've done quite a bit of work with MVC. MVC can be a good pattern to be use for some applications. So, it's not that I'm a hater. It's just that more applications need to consider the alternatives where they are better suited and a lot of programmers are not thinking beyond MVC.

Some Alternatives

So, what are the alternatives I hear you asking? Two that I'm familiar with (there are more than two):

Take a look at these, learn them, understand them, and use them.

Saying No To MVC

There is a time to say no to using MVC. When a better pattern is available and someone suggests MVC saying no is not only appropriate but our responsibility as we are architecting. This happens more often than you might think.

Reader Comments

How could you leave out: http://www.garfieldtech.com/blog/mvc-vs-pac

:-)

I would add the following substantive gripe about MVC: It is very likely *not* the appropriate model for web applications.

MVC was designed with single-purpose GUIs in mind. The idea was to control only one well-defined, special-purpose view that performs exactly one task.

But this isn't really how over 90% of web pages work. Sure, many have "main content" sections, and on occasion, the content section has only one purpose (e.g. to hold the content of an article).

But even in this near-ideal case, we have two problems:

1. Secondary content
2. Inflexibility of the core pattern

Secondary Content:

Almost every web page pushed out of a server has secondary and tertiary pieces of content, which means the single MVC pattern does not mesh well.

Typically, we relegate this content to sidebars, headers, and footers. On occasion, however, this content becomes visually part of the "main content".

But this data gets an odd treatment. The main controller is typically blissfully unaware of its existence. In fact, the content sort of takes on a schematic life of its own, and strange methods of processing creep in, like deciding in the view layer of the main page's MVC what data will go in along the rails or in the footer.

But how can this be good design? Now we've increased the requirements of the functionality of a view layer -- the very component in MVC that is supposed to be least active in deciding what is displayed suddenly becomes responsible for (let's face it) the majority of the decision making about what is shown where.

Of course, this problem can be mitigated, but not from within the MVC pattern. Some additional not-very-MVC approach needs to be created that will help determine how to map the request to the secondary and tertiary content generation features. The PAC pattern partially addresses this (since PACs are nestable on the abstraction layer). But even this seems a little stilted to me, as the top layer controller ideally has to determine what the next layer controller is supposed to be.

Inflexibility of the Pattern

The second problem I have with MVC -- and this is the big one -- is that MVC is not flexible or extensible. There is *once* controller per request, and this controller should know how to do everything that the application needs done to display the page.

But what if I want to group multiple behaviors together on a web page? What if I want to display an article and a comment form? Conceptually, these are two different tasks. They should be handled by two different processes. And ideally, I should be able to modify the comment form without having to make any changes to the article generator.

Before you start objecting, let's step back one more level: During the rendering of a page, *every functionally discrete section of the page* should also be independent to the greatest extent possible. I should be able to easily enable and disable things along the rails. I should be able to re-order the processing of items (not the display, the processing) so that I can make certain data available earlier. I should be able to very easily swap in and out subcomponents like authentication systems, ad tracking, loggers, etc. In short, I should have the flexibility to modify *components* without having to rewrite massive parts of my controller logic. (This is more in line with the Front Controller pattern than the MVC pattern).

Again, the typical mitigation strategy for this problem is to write *additional* subsystems to tack on this sort of functionality. Sometimes this is done in the Controller layer. Too often it is done in the View layer (contra the contract).

But once we start writing these massive subsystems (one need only to look at the methods Drupal, Wordpress, and Joomla! use to generate rail content), one must ask whether the problem isn't the irritating demands of customers or bosses, but the inflexibility of MVC -- or its ill-suitedness to web design.

Those are my two major arguments against MVC. But I want to offer one final bit of fodder: The real reason, I suggest, that MVC is enjoying so much fame has mostly to do with the model layer, and a huge, huge flaw in our current software development methodology.

The problem is that we have been wedging objects and documents into relational databases.

The model-layer of MVC, O Great ORM!, provides for us a huge simplification to the ill fit between high order objects (documents-users-comments) and database constructs (tables-rows-fields).

PAC facilitates ORMs easily. CoC/CoR does not provide a clear location for an ORM or data abstraction layer -- but then again, it's not supposed to. But in either case, the point may very well become moot. The new generation of data storage tools, from NoSQL databases to high-performance temporary datastores, may usher in a new standard for data storage. If this happens, suddenly the Model layer of MVC -- at one time it's most compelling feature -- will become all but irrelevant, a mere checkpoint for verification of data before it's handed off to a smarter storage engine.

So let's re-open the dialog about MVC, and let's take a good hard honest look at what we're getting from it, versus what we're forced to give up to it.

Personally, I think its not that MVC is bad, just the implementations of it and the frameworks.

MVC is not bad. It is where developers try to shove a square peg into a round hole. They try to use MVC where another pattern fits better. Where they have to beat on MVC to get it to do what they want because they are trying to use it in ways it was not meant to. In ways other patterns were meant to.

Saying no to MVC is not about saying MVC is bad. It's about saying MVC is not appropriate here.

What pattern most represents Drupal's hook-able architecture?

Good question.

Drupal is closest to a PAC (Presentation-Abstraction-Control). Larry Garfield wrote a blog post about this at http://www.garfieldtech.com/blog/mvc-vs-pac.

Most hooks (not all of them) are implementations of the observer pattern. Instead of them being objects with registration they are name spaced functions. One of the really nice things about name spaced functions in PHP is that you don't have the overhead of registering them on every page load (which could take a bit of resources). On the down side autoloading is not so easy.