MVC
Published: 4 January 2014
Tagged:
Pattern MVC

A translation of Bill Sanders’ article on implementing the classic MVC meta-pattern in Smalltalk-80



Preface

This is not an introduction to the MVC model, but an overview of its implementation in Smalltalk-80 to understand the original intentions and functions of the triad. Classic MVC will help better understand the subsequent evolution of patterns that appeared later. We will look at how a simple MVC application works in Smalltalk-80 and study how it can be implemented in ActionScript.


Model-view-controller (MVC) — a software architecture pattern in which the data model, user interface, and control logic of an application are separated into three distinct components, so that modification of one component has minimal impact on the others.


Implementing Model-View-Controller in Smalltalk-80

The MVC model facilitates separation of concerns in the development of interactive graphical applications. Application logic and state, how users interact with the application, and how the application state is presented to the user are all handled by separate elements of the MVC triad. Smalltalk-80 uses the MVC metaphor, providing built-in support for interactive application development.


The idea was to provide a set of built-in user interface components, such as buttons, menus, and lists, that can be plugged into a GUI application. To effectively use these built-in interface elements, the implementation had to be built according to MVC. Let’s look at a conceptual diagram of a Smalltalk-80 application.



MVC diagram in Smalltalk-80 (Krasner & Pope). All objects in Smalltalk communicate with each other through messages, which is the way of calling object methods. At first glance, the MVC diagram looks a bit strange. Model-View and Controller-Model have bidirectional dependencies. The second interesting aspect was that user input goes directly through the controller. This is a significant change — we usually expect the user to interact with interface elements in the View, not in the Controller.


In Smalltalk-80, all data from input devices is fed directly to the controller. Let’s briefly look at how MVC is supported in Smalltalk-80.



MVC classes in Smalltalk-80

There are three abstract classes called Model, View, and Controller. All concrete implementations of models, views, and controllers must be subclasses of these abstract superclasses. Let’s look at the classes (this is an abbreviated description — see Krasner & Pope).


  • Model: the abstract superclass Model implements common model behavior. It implements the dependency maintenance mechanism.

A View can register with a concrete model to become a subscriber and receive change notifications. If a concrete model broadcasts its messages, they will be automatically sent to all its subscribed views. This is an implementation of the Observer pattern (a behavioral object pattern). A concrete model does not directly know about the views that depend on it.


  • View: the abstract superclass View implements common view behaviors. A built-in set of view subclass components (e.g., StandardSystemView — a standard window, and TextEditorView — a text editor).

Views can be nested to develop complex user interfaces. For example, StandardSystemView (i.e., a window) contains a view component called TextEditorView. Each view can have one model and one controller. Built-in components have a predefined default controller class to implement their standard behavior. To instantiate a component, you need to configure your model and display the component. The component then initializes the default controller with its model instance and registers with it for messages. When a component is closed, all nested components are released. When a view is released, it removes its message subscriptions from the model. If you want components to have unique behavior, you can create a custom controller for them.


  • Controller: the abstract superclass Controller implementing common behaviors. Each controller has a reference to one model, one view, and a global variable called a sensor, which provides an interaction interface for input devices (mouse, keyboard). The abstract controller class implements its common behaviors for defining a concrete controller and its corresponding view. If a concrete view is active (currently being used by the user), its controller manages all user input.


The controller must have a direct reference to the view — for example, to know whether the mouse cursor is currently positioned over a particular view. Importantly, only controllers, not views, receive input data (from keyboard or mouse).



Key features of MVC implementation in Smalltalk-80

  • views can be nested;
  • each built-in component (e.g. ListBox) is a view;
  • each view has a corresponding controller;
  • a controller notifies its view when it becomes active;
  • the active controller (whose view is currently active) receives data changed by the user via input devices;
  • a controller can update the view (component) based on user actions;
  • a controller modifies the model based on user actions;
  • a view updates itself via the observer, synchronized with the model.