Model View Controller

In Smalltalk-80™ the user interface was created around a framework known as Model-View-Controller or MVC. Over time this has been seen as a classic framework but some deficiencies have surfaced.

MVC applications are split into several triads each of which comprises a relationship between a Model object, a View object and a Controller. This interaction looks as follows.

The red link denotes dependency notifications. Traditional MVC implementations have further split the Model into Domain Models and Application Models which are also loose coupled using the dependency mechanism. The requirement was certainly present for something to sit between the View&Controller pair (which are usually quite generic) and the Domain Model which is business specific. The Application Model (or Tool) layer is therefore allowed to "know" something about the user interface while it manipulates the domain.

The resultant architecture looks as follows.

Problems

Increasingly we came across problems with this approach. Most were caused by the Observer connection between Application Model and view. The difficulty here is that, as we have already said, the AM is allowed to know about the existence of the View but not vice versa. For example, the AM may be responsible for enabling and disabling view widgets or changing colours to show validation errors and such like. However, because the coupling between it and the View is loose it becomes difficult for this sort of interaction to take place. VisualWorks™ users will be familiar with the roundabout:

builder componentAt: 'aViewName'

method of accessing Views from within the Application Model.

One of the problems here is that the dependency mechansim between tool and view is being used for two, rather different purposes. First it is being used to implement the Observer pattern. This allows several Views to observe a single Model and display changes to it while the Model knows nothing about these Views. However, we have already seen that an AM needs to be able to communicate with its Views so the reason for using Observer is weakened here. As soon as you have to use componentAt: you've broken Observer.

Secondly, the dependency mechanism allows an adaptive coupling between the Model and View. We want to be able to plug different generic Views onto more specific Models in many different ways, for maximum re-use. Thus the interface between the two needs to be flexible or simple or both. This ability is implemented in VisualWorks™ using ValueModels. This is the real reason for the loose coupling between AM and View.

What we really want, though, is a tight coupling between AM and View but a loose coupling between Domain Model and View. Rotate the triad slightly and we get the Model-View-Presenter framework.