2006-11-06

MVC - Revisited

The MVC pattern is easily the best known pattern around. What is interesting though is that everyone understands something different when refering to this pattern which indicates to me that there are concepts within the pattern which are not clearly delineated and have overloaded designations.

I think a key to a better understanding of this pattern is to abandon the too generic name 'Controller' and replace it by more succint names according to what the controller does.

In the classical Smalltalk MVC the Controller interpreted the input (mouse & keyboard) Event Stream and called upon both View and Model to make modifications. But with the advent of Widgets inside of a Window or Dialog, the role of the classical Controller somewhat degenerated into what I would like to call an EventHandler (a.k.a. Interactor).

The EventHandler collaborates with the View part of a Widget and converts the syntactical Event Stream into Semantical Events according to the geometry of the Widget. These Smantical Events are not realized by the Interactor though (i.e. the Interactor does not directly make changes on the Model or View) but he passes the Semantic Events in form of Actions to another instance - the ActionHandler.

The ActionHandler is now a different kind of 'Controller' who receives Actions from the Widgets and then calls upon the Model or View to carry out changes. It thus converts Actions into Commands where Commands reify the changes to be done on the View or Model. The execution of Commands might require user confirmations or the request of additional information from the user.

This latter aspect of requesting further user input might lead to the display of another Window or Dialog with its own ActionHandler. Instead of putting this Window transition logic into the ActionHandlers, a further 'Controller' breakdown consists of introducing an entity who controlls the staging of the separate Forms (i.e. Dialogs or Windows) of an Application - the StageHandler.

When a Command executes on the Model the classical MVC design builds upon a notification mechanism (the Observer pattern) to inform the View to update itself from the changed Model. In the Widget based MVC variant, the update of the View mainly consists of updating the Widgets of a Form. Instead of using notifications Commands are sometimes used to update first the Model and then the View (i.e. the Widgets) by pushing information into the Widgets. The Commands thus also fullfill an adapter role between the Model and the View, which might otherwise not be pluggable.

To allow pluggability between Model and View and thus to free the Commands from the 'manual' update of the View yet another 'Controller' is identified: The ModelAdapter. This ModelAdapter sits between both Model and View and handles interface adaptation, notification handling and the maintainance of Selections, so that the View operates on the intended subset of the Model. The Commands communicate with the ModelAdapter to set, change as well as read the Selections.

The domain knowledge is encoded in the Model. As this is mostly not only passive knowledge but also active behaviour, the Model can be separated into plain Data and an Engine 'Controller'. This Engine might apply 'physical' forces onto the Data and is independent from the GUI/Application layer above.

So, at the end, we exchanged the one classical Controller into the following 'Controller's:
  • EventHandler: turns EventStreams into Actions
  • ActionHandler: turns Actions into Commands and applies them
  • StageHandler: controls the transition from one Form to another
  • ModelAdapter: adapts Model and View and holds the Selection
  • Engine: applies 'physical' forces to Data

I hope, the above can help in finding a common understanding of the MVC pattern for modern client side applications.

Cheers
marc