MVC is wrong for the web (?)
Filed under: mvc web programmingI've got a vague notion about web development that I'm jotting down here mostly to help me clarify some thoughts and as something to revisit sometime down the road. The question mark in the title reflects my uncertainty about some of what I'm positing below.
First of all, I don't think that MVC as it's applied to the web is the same MVC first described in Smalltalk. Mark Ramm gives a nice summary of what MVC meant in the Smalltalk environment and it's clear that it isn't very close to what we're doing today. A notable difference is what the Controller meant to Smalltalk apps vs what it means (or doesn't mean) to web applications.
Here's a short list of things I see wrong with MVC as it's currently applied to the web:
- "Designer-friendly" template engines are counter-productive. Designers ought to be writing CSS, not HTML. Programmers ought to be generating HTML and designers styling it. HTML is the output of the program and should have as little to do as possible with how it's presented.
- The Model, as it is commonly used, is a merely a language-specific repetition of what is already defined elsewhere (the database).
- The Controller, having lost its purpose as a place to control flow, has been relegated to an ill-defined (but required!) place to shove anything that isn't strictly Model or View.
- The View exists solely to insulate designers from code and the programmers from markup.
To be clear, I'm not suggesting that MVC is bad, just that it's misapplied to the web. The goal of separation of concerns is a good one, but I think the lines between concerns are poorly drawn for most web applications.
Django redefined MVC into what they term Model-Template-View (MTV), which at one level is just shuffling terms around, but I think it reflects a goal of eliminating the Controller. I originally didn't really get the point of this, but now I'm thinking they didn't go quite far enough (although had they gone the whole distance, it might have hurt Django's acceptance).
So here's some general thoughts about what should be done in place of MVC.
- Make HTML generation programmer-friendly, not designer-friendly. This means making HTML look like code and HTML generation natural in the context of regular code. I'm thinking in terms of the Lisp philosophy of growing the language toward the program, in other words, by using an embedded language/internal DSL for generating markup.
- Code that previously got lumped into the Controller becomes part of the Model or is expressed directly in the View. This revives an older paradigm where work was done "in the database" (i.e. in stored procedures). Stored procedures have a lot of advantages (they function outside of the framework, can take advantage of transactions, etc). The main downside to stored procedures is that most databases don't provide nice tools for dealing with them and they often require a separate programming language than what is used in the main application. This can be addressed by building those tools and by using databases that support programming stored procedures in multiple languages (e.g. PostgreSQL). Alternatively, an ORM layer could be used, although this approach has drawbacks as well (poor performance, added complexity, increasing distance between programmer request and actual function).
- Designers write CSS only. This means the framework should help programmers generate markup with minimal fuss.
- The application is the Controller. In Smalltalk, the Controller is where things like input loops occurred and program flow was defined. On the web this task falls to the web server event loop and the framework's dispatch mechanism.
At the end of it all, we're left with what seems to amount to Model-View-Style. To summarize:
- Model: the database and related procedures, the sum of which equates to business logic
- View: presentation logic, including markup generation. The Model is directly accessible from here in the form of objects and methods.
- Style: CSS
To rephrase this in terms of a familiar framework, consider that Django is the Controller, the Model is the same, and the View subsumes the Template in their MTV model. If we acknowledge that there's little reason to create a line between the View and the Template in this model, then we simply merge the two and are very close to what I'm talking about (with the notable exception that Django template code isn't appropriate to the solution).
I'm still a bit doubtful about using stored procedures in spite of their obvious advantages. It's a very limiting decision in some ways (reduces choices of databases and languages, raises deployment concerns), but I think it's worth considering. It would be more appealing if things like ORMs (which are slow and complicated) could be rendered moot by having stored procedures return native objects, but that brings it's own concerns and complications. At the end of the day, a more traditional (non-DRY) Model could be used without affecting the overall architecture significantly.






