Vespa: A better MVC

Monday, 23 June 2008

Vespa is a refinement of the old MVC (Model View Controller) architectural pattern that better reflects how Web applications actually work. MVC has been around for a long time, but many implementations have some annoying inconsistencies. I have refined the basic MVC pattern in light of typical usage patterns I’ve encountered; the result makes it easier to design an MVC application in a clear, modular manner.

The Model-View-Controller application structure came from Smalltalk and has been around for 25 years or so. The Model refers to the application classes, the Controllers are the classes that interpret and respond to user input, and the View displays the results to the user. Web MVC frameworks like Struts, Spring Web MVC and Ruby on Rails use a similar kind of structure, refined to fit the way the Web works.

Problems with MVC

Here’s the standard MVC overview. There are three dependencies. First, the Controller updates the Model and extracts Model data. Second, the Controller packages Model data for the View. Third, the View displays data from the Model.

Model View Controller

A few things bothered me about the MVC architecture as implemented in Spring and elsewhere.

1. The Controller classes depend on the View. The Controllers create a Model object which is displayed by the View; because of this, the Controller needs to know which data to include in the Model, because the View is expecting certain named data items. In effect, the Views have an implicit interface that the Controller must honour. This seems wrong if the Controller processes input and the View displays output — they should be completely decoupled.

2. In many cases, Controllers do too much work. For example, a typical edit controller carries out three separate functions. First, it displays a form for editing a record. Second, it processes user input (e.g. “user clicks the Delete button”). Third, it creates a Model and forwards to a View (e.g. show a list of widgets). These activities are not necessarily related, so why bundle them together in one class, or even in one package?

3. The definition of Model seems inconsistent. Originally the model referred simply to the data that was to be displayed in the view. This is sometimes referred to as a Presentation View. However, the J2EE “Model 2” MVC architecture considers the Model to be all domain-specific code, including data but also including business logic. Rails is similar, but the Model is tied to the database layer, and business logic often seems to live in the Controller. Frameworks like Spring revert to the original meaning, where the Controller creates a Model data structure for use by the View.

These are not really problems; they are just a result of the high-level nature of the MVC structure. It’s easy to understand MVC, but it’s impossible to follow it strictly because the structure itself is ill-defined. Drilling down insde the MVC pattern lets us bring out more detail and understand better the responsibilities of each component. The Controller → Model dependency is straightforward, but the other two dependencies can be refined so as to clarify the MVC architecture.

Refactoring the Controller

In many cases, a Controller carries out several tasks. For example, a typical edit controller carries out three separate functions: form display, input processing, and results display. Code like this is typical.

Controller:
if (editing a new record) then
   Display the form
else
   Save changes
   Display the updated record
endif

Often, the code to set up and display a form has only a tiny amount in common with the code to just display a record. The form Controller code need to retrieve values for dropdown menus and checkboxes and other supporting information; the form View needs client-side data validation and other presentation code. And the code for saving changes has little in common with either of the views. This suggests separating the two. Controller code that sets up a view doesn’t need to update the Model; it only reads it. This type of Controller I call a Presenter. A Controller that updates the Model is called an Actor.

Model View Actor Presenter

With this structure, the three tasks previously managed by the single Controller become the responsibility of three separate objects: two Presenters and one Actor.

Presenter 1:
Display the form

Actor:
Save changes

Presenter 2:
Display the updated record

Also, note that the Presenter depends on the View (as the Controller did before) but there is no dependency between the Actor and the View. This confirms that the Presenter and the Actor really are separate kinds of object.

Refactoring the Model

The other dependency is that of the View on the Model. To clarify this, I noticed that “Model” sometimes refers to all classes that embody application data, and sometimes it refers only to specific subsets of that data: for example, a specific data structure used by a specific View (as in Spring), or an object-based abstraction to a database (as in Rails). For my purposes, I have decomposed the Model into two separate pieces. One part is the plain data entities that represent business data; these are called Entities. The other part is the code used to store and manipulate the entities; this is called the Store.

Starting from the basic MVC, here’s what happens when we split the Model into Entity and Store.

Store Entity View Controller

This shows that the View depends only on the Entity, not the Store. This makes sense, since the View only needs to display the basic data objects provided to it by the Controller; it does not access the Store itself.

The Vespa pattern

Putting these two ideas together gives us a unified diagram showing how the five areas of the application depend on each other.

Store Entity View Actor Presenter

This diagram makes it clear that everything depends on the Entities. This is what we would expect. The essential function of an application is to manage data; we would therefore expect all areas of the application to depend on the data to some extent.

Since the Entities are essentially a global dependency, we can simplify the diagram by making that explicit. The result is an architectural pattern that I like to call Vespa. (It’s an acronym for View, Entity, Store, Presenter, Actor; but it looks ugly if written in capitals. It’s also a brand of motor scooter, so conjures up images of sleek, fast, shiny things.)

Vespa architecture

The Vespa diagram is almost as simple as the original MVC diagram, but it is far more instructive and useful. It’s easy to see where each application function fits and what other functions it depends on. It’s particularly appropriate for Web applications. If you’re writing a simple application or a custom framework, you can follow the Vespa architecture directly. Even if you’re using an existing framework such as Spring, Vespa can help to clarify your thinking as you organise your Controllers.

Tags:

14 comments

You can leave a comment, or trackback from your own site.

  1. Has Vespa been coded into a framework yet?

  2. Not by me at least. I have been toying with coding Vespa for Spring Web MVC and also for CodeIgniter. But I really don’t have time to do it, so don’t hold your breath. 😛

  3. Mark Bennett (no rel

    You might include a link to the official vespa home page. Google is returning other contexts for that term today.

  4. Finding the official Vespa home page is left as an exercise for the reader.

  5. Just checking up on this post. Ever get anywhere with it?

    I’m running into situations myself with MVC where my view is cluttered with conditionals, and I’m looking to polymorphism to fix it. How would you see Vespa dealing with this?

  6. Views full of conditionals are often better refactored into two separate views. Vespa does not explicitly address this, though in the example above you can see how breaking up a Controller into two Presenters and an Action naturally suggests having separate Views too.

  7. I really like this concept, though I do not believe that the ‘Presenter’ should have any dependancy upon the ‘Store’. I believe that only ‘Actor’ would need to have this dependancy.

  8. The Presenter needs to access the Store to retrieve the Entity objects to pass to the View.

  9. Actor needs to access the store, and presenter access store for passing data to the View. What if we need both of 2 actions done (ex: actor updates the store, then presenter access updated data for passing to the view) ?

    And, I could not find out official website of Vespa structure. Is it still alive ?

Leave a comment