Model-View-Controller architecture, part 1
By Dmitry Kabanov
Model-View-Controller (MVC) is one of the most common design patterns used to develop applications with graphical user interfaces (GUI), especially in object-oriented programming languages.
I summarize here three initial works on MVC from 1970s and 1980s along with my comments.
Introduction
It is actually a meta design pattern that specifies splitting of software components in classes with distinct responsibilities. Models are responsible for reflecting the application domain including the data that the application operates on. Views are responsible for presenting the models to the user. Controllers are intermediate components that process user actions and request models to read/modify the data in response to these actions.
This idea was formulated in late 1970s in Xerox Palo Alto Research Center, and passed through multiple transformations, as the way GUI applications are written nowadays is not exactly the same as it was then.
Particularly, modern applications are based on GUI toolkits that provide common widgets such as text fields and buttons, and processing user actions does not require an application programmer to implement code to determine which widget the user has clicked on, although it seems this was an important responsibility for controllers in the original idea, as will be seen below. Hence, the meaning of Controller has fluctuated, as many authors use the same word in different meaning (for example, in the GRASP patterns by Craig Larman, Controller object is non-UI class that handles external input, which, as we will see below, is not exactly how Controllers were thought of when the idea of MVC was created).
There are multiple variations on the idea of MVC, such as
- Model/View architecture in Qt
- Model-View-ViewModel architecture in SwiftUI framework
- MVC web frameworks like Django.
Nevertheless, the main idea of MVC, the idea of Separated Presentation, is preserved in all variations.
One of the goals of reading initial works on MVC for me was to see how the MVC was defined initially and why there are so many variations of this pattern.
To make it easier to understand MVC, it is useful to understand these design patterns:
- Observer pattern that allows one object (Observable) to inform indefinite number of other objects (Observers) about some event;
- Composite pattern that allows to work with hierarchical projects as with single entities;
- Strategy pattern that allows one object (Context) to delegate an operation to another object (Strategy).
Original MVC idea from PARC by Trygve Reenskaug
The original version of MVC was developed by Trygve Reenskaug in 1979. The following original documents can be read at his webpage at the University of Oslo:
“Thing-Model-View-Editor”, 12 May 1979
This technical note seems to be the first prototype for the MVC architecture, although there are four, not three, objects (the author calls them metaphors) in this note.
He provides examples of these objects from a software for planning system for large projects, that is, the projects, where one must do task management not in the head due to the number of different tasks and participants.
The first object in this “quadriad” is Thing, which is actually
not something that belongs directly to software but something
from the real world that is of interest to the user,
something that the software is developed for.
In the planning system,
the examples of Things are Gannt diagrams
and activities
,
that is, tasks with their predecessors
(previous tasks)
and successors
(the following tasks).
The Model in this note is more or less the Model in MVC.
It is a representation of Things in the form of data in computer,
along with operations on these data.
Using the large-planning-system example, activities
are represented in the software as objects, where the collection
of activities is a field in the class NetworkModel
, with the collection
being represented as a dictionary.
That is, the Model actually models
the objects of the real world (even if they are abstract) in terms
of data structures and object-oriented classes.
The author also states the fundamental postulate of MVC here:
the Model is not concerned with the visual representation
of the data on computer display.
The View in this note visually represents the Model,
and there can be several Views attached to the given Model.
The first two examples are lists of networks and the list of activities
in a given network.
The author models these lists as classes
NetworkList
and ActivityList
, which are subclasses of ListView
.
[ I actually do not think that this idea of subclassing widgets
(that is, generic GUI components like ListView
) has survived,
as nowadays one would use just a generic List
widget parameterized
by the actual list that it displays, without introducing subclasses. ]
When the author explains how ListView
is organized, it gives us
also the hint that the Editor (a.k.a. Controller) is basically
attached to a given widget, while he gives examples that the Editor
is responsible for organization of scrolling inside the view
and reacting to the selected item in the ListView, e.g., by informing
other views that an item is selected.
Interestingly, the last statement is formulated as “The Editor
then asks the ListView
and any other Views to select that item”,
which shows that apparently the Observer pattern was not the initial
part of MVC but appeared later.
What I mean is that the Editor was responsible to inform one or more
Views about changes directly, not the Model, indirectly, via sending
notifications to observers.
I think this idea is used nowadays in the variant of MVC called
Passive View by Martin Fowler:
one of the reasons for that is that it improves
testability as the more active Controller can be tested
with the mock of its View so that tests are independent of GUI framework.
Additional quote I would like particularly put here as the hint that the views must be relatively passive in terms of the software functions as they are already reponsible for displaying: “This separation of user interface and actual command execution provides for great flexibility in the Editor.”
Then he gives an example of ActivityText
view which is a subclass
of TextView
, generic component that is able to display textual
information.
The next two examples are representation of activities inside a given
network in the subclass of the DiagramView
, which allows to visualize
activities as rectangles with connections to their predecessors
and successors.
Here there are two views - one shows smaller networks with activities
names and the other shows larger networks without activities names
and on the gridded background.
Here he mentions that not every aspect of the View can be deduced
from the Model itself as the Model does not have any information
about where to put on the screen a particular activity in the network.
Here the author proposes again to model them as subclasses of the common
view or as one view as a subclass of another.
However, he also proposes here to have just one class DiagramView
that is parameterized by some field with values small/large
,
so that an appropriate visualization could be chosen.
The last two examples of views are GanntDiagram
(subclass of ChartDiagram
)
and ResourceDiagram
(subclass of DiagramView
).
Here the most interesting statements are that these view should provide
operations that allow the user to retrieve some information
by, say, pointing at some activity in the GanntDiagram
.
The last metaphor in this note, Editor, is “an interface between a user and one or more views.” Editor is responsible for providing commands to the user in the form of menus and coordinating views.
The most interesting example of Editor given by the author is the Demonstration Editor. This Editor shows several panes in a single window, so that these panes reflect the modelled Activities network. Here the author states the following:
“Each of its panes is a sub-Editor that communicates with its particular View. It also gives commands to the demonstration Editor and receives commands from it.”
which is basically the idea behind the much later developed patterns Presentation-Action-Control (1987) and Hierarchical MVC (2001). Hence, the MVC from the very start was considered as a Model with a collection of Views and Editors (Controllers) that are connected to different aspects of the Model, with the Editors potentially being organized hierarchically.
Second technical note, 10 December 1979
The second note is actually very short (two pages) but has extremely important statements about the role of each component in MVC.
- “Models represent knowledge”, that is, they represent the domain in which software operates. The author also notes that usually there are multiple models if the application domain is nontrivial.
- Views represent models visually. The author states also that the views are coupled to models (or submodels) as they can directly request data from models and can send messages to models to update themselves.
- “A controller is the link between a user and the system. It provides the user with input by arranging for relevant views to present themselves in appropriate places on the screen.” The author also states that “Conversely, a view should never know about user input, such as mouse operations and keystrokes. It should always be possible to write a method in a controller that sends messages to views which exactly reproduces any sequence of user commands.”
I find this short technical note very insightful. I have understood the idea of a Model long time ago: it is in general a whole network of collaborating objects, representing application domain. Also, the statement that Controller is responsbile for arranging for relevant views is very interesting as this is not obvious to understand, for example by reading about MVC in Wikipedia.
The idea of views not knowing about keystrokes and mouse operations, I think, did not survive. I think with modern toolkits the views are actually responsible for knowing about these things, while Controllers are actually not concerned with these things anymore. However, I think Controllers are in general written in such way that tests should be possible without GUI.
Paper by G.E. Krasner & S.E. Pope from 1988
G.E. Krasner and S.T. Pope published a paper “A cookbook for using the model-view controller user interface paradigm in Smalltalk-80” in the Journal of Object-Oriented Programming in 1988 that was, AFAIK, the first published work about MVC not from the authors.
One of the most interesting aspects of this paper for me was that the authors basically mention several design patterns several years before the book by Gang of Four that made the idea of design patterns popular.
The authors mention in the beginning:
“The use of pop-up versus fixed menus, the meaning attached to
keyboard and mouse/function keys, and scheduling of multiple
views should be choices that can be made independently of the
model or its view(s)”, which further augments the idea that the Controller
component is responsible for orchestrating the views,
found in the Demonstration Editor
example from the first technical
note by Trygve Reenskaug.
“Each view may be thought of as being closely associated with a controller, each having exactly one model. But a model may have many view/controller pairs”. This is a very important idea, that they will further use in this paper by introducing the Observer design pattern to MVC.
The authors state that the Model can be as simple as an integer, for example, for a trivial app that counts how many times user has clicked on a button, or a complex object consisting of multiple objects. This is the same statement about Model as was in the original formulation.
Additionally, the authors explictly state that the Views obey to the
Composite design pattern, that is, that the views can have subviews
and be put into superviews.
Therefore, a message display
(on a Model update)
is passed from top-level views to its subviews transparently.
“Controllers also deal with scheduling interactions with other view-controller pairs: they track mouse movement between application views and implement messages for mouse button activity and input from the input sensor.” They also say that the menus are in the realm of Controllers.
The interaction between these three components is as follows. The Model does not know anything about controllers and views. The Controller requests updates on the Model in response to user actions. The Model carries out the requested operations. As they can be multiple views connecting to the same Model, they all must be updated when the Model is updated to preserve consistency. This is where the Observer design pattern appears (it is called Dependents in the paper): Controllers and Views connected to the Model register as its dependents, and the Model informs them about the changes, which can be parameterized, so that different types of changes are passed only to the dependents that are interested in them.
When all the interested dependents are informed about the changes, they can update themselves. Views ask the Model about the updated state. Controllers may also update themselves in reaction to the Model changes, for example, some menu items can be enabled/disabled due to the new Model state (e.g., when a text document is changed after it was saved, the Controller can enable “Save” button in the toolbar). In principle, the View that represents these toolbar can enable this button—this is one of the situations where distinction between Controller and View is blurry. The way of thinking about why the Controller must do it, not the View, is that the View visualizes the Model itself, while the Controller is responsible for graphical parts of the application interface).
Conclusion
So after reading these three original works, from 1979 and 1987, I can say the following:
- the original idea of Model as a representation of application domain was there from the very beginning;
- the idea of hierarchy between Controllers was also there from the very beginning, as a way to manage complex views consisting of subviews;
- the idea of Model being completely oblivious to Controllers and Views is one of the ideas that is preserved in all variations on the MVC idea;
- the idea that Controllers know about mouse/key events, I think, in general, did not survive, as now GUI toolkits, which Views are based on, handle these things themselves, and Controllers’ main responsibility is to pass external requests to Model;
- both original works by Trygve Reenskaug as well as the paper by Krasner & Pope state that quite often not everything about application behavior can be derived from Model: a lot of aspects, such as disabling menu items or buttons, how to display data, and so on, lead to the idea of Presentation Model (or ViewModel) which is responsible for tackling these aspects, which are more application-centric, than domain-centric;
- the paper of Krasner & Pope introduced the Observer design pattern to MVC with the goal of decoupling Model from Controllers and Views and to simplify handling updates of multiple Views attached to the same Model;
- the paper of Krasner & Pope introduced also the Composite design pattern for structuring Views, although to some extent the Demonstration Editor example from the original technical report by Trygve Reenskaug introduced the same idea, although not explicit.
Thank you for reading!