Model-View-Controller (MVC) has become the dominant pattern in user interfacing applications. It’s Object Oriented, fits nearly 100% of business related applications and provides a fair and clear separation between the program functional blocks.
The Model is the application’s idea of the data to be manipulated and is in charge of
interfacing with the data stores and manipulating the data so that it is presentable to the
user. The View is the module in charge of all the display functions, it pulls data from the
Model and feeds user action back into the Controller. The Controller in turn takes the
user actions, verifies the business logic and manipulates the Model accordingly.
The MVC pattern neatly circles from Model to View, View to Controller and from Controller back to Model. This makes the contracts between modules fairly simple and the application flow predictable. In the wild things are seldom so clean cut and one finds shortcuts and shortcircuits that don’t belong to the pattern but work around implementation issues that stem from problems in the application architecture.
One of the great strengths of MVC is allowing for a user driven design. The View is sketched up independently and can be prototyped and tested on the user without the rest of the application being there. The Model is then designed for the View’s needs. Meanwhile the Controller can start to implement the hard business logic and then the UI interaction logic.
The MVC pattern was successfully applied to Web based applications and can be found on the
popular frameworks like RubyOnRails and Django. But when we start to move into “Web2.0” type
applications MVC starts to present some challenges.
So, reviewing the contexts, we have the database context with very high bandwidth to the data and poor latency to the user. We have the server context which usually sits very near the database and far from the user and finally we have the client (or browser) context which is very close to the user but has latency and limited bandwidth to the server and database contexts. The client context is also totally untrusted while the server and database context are trusted. This is a large departure from the traditional MVC pattern where there were no untrusted contexts.
Having defined the contexts for our new Web2.0 pattern we must now define the program roles to
run in them. We can start by trying to map MVC into our contexts.
The Model traditionally resides partially in the database context as database views. With relational databases such as MySQL or Oracle there will be another part of the Model in the server context handling the SQL interface.
We want interactivity so the View should reside completely in client context. That’s commonly not the case though, as a part of the View goes into the server context to serialise the database results into HTML or run sensitive parts of View code we don’t want to trust to the client context.
Finally, the Controller will be in client context for the sake of interactivity. But again, the client context is untrusted so the business logic part of the Controller and the Model update interface must run in server context and for speed some parts of it will even run in database context.
This is definitely not a winning pattern. It’s confusing and breaking out of the single context of old makes it much harder to keep OO straightforwardness. There must be a better way.
First thing we’ll do is throw away OO. I’ve lost half the audience at this point, the rest bear with me please. Instead of Objects we’ll focus on functions. What functions must the program do and in what context do they work best ?
The most obvious function is the datastore. At some point the program must load data from the past and save data for the future. And the obvious context for the datastore function is the database. And to make the datastore function simple we need to do away with the bit of the Model that (de)serialise data into/from SQL. Luckily, there’s a new generation of databases designed specifically for the Web that do away with SQL altogether (and relations in the process) and present a RESTfull JSON interface.
Another obvious function is interacting with the user. We have to show data to the user and get their feedback and hopefully in the process make the user happy. This is what I call the display function and it lives naturally in the client context. Keeping the display function in the context closest to the user ensures the best interactivity but on the other hand the client context is untrusted so there’s a number of interesting and useful operations we can’t do in the client context.
We’re left with the things we haven’t done so far. That’s the things we do in server context, the things that involve input validation and secrets. I’ll call this the policy function.
So, reviewing the functions, we have the datastore function which is roughly overlaped with the Model Object. The display function covers the View and a part of the Controller and finally the policy function covers the rest of the Controller and may do some Model things.
(end of part 1. stay tuned)