Separated Presentation: The Classic Model-View-Controller Pattern
This is not an introduction to the MVC pattern, but a look into its implementation in Smalltalk-80 to understand the original intent and function of the Model, View, and Controller triad. Starting with the “classic” MVC helped me understand the evolution of the presentation patterns that came after it. We will look at how a simple MVC app works in Smalltalk-80 and examine how it can be implemented in ActionScript. I am not a Smalltalk programmer and my first task was to find some good resources.
Trygve Reenskaug is credited with the first MVC formulation in Smalltalk in the late 70′s. However, the MVC metaphor was burned into Smalltalk and matured after Reenskaug left Xerox Parc. I found two useful resources on MVC in Smalltalk-80. The first is A cookbook for using the model-view controller user interface paradigm in Smalltalk-80 by Glenn Krasner and Stephen Pope. The second resource is Applications Programming in Smalltalk-80: How to use Model-View-Controller (MVC) by Steve Burbeck.
Although comprehensive, Krasner and Pope’s article is very readable from an ActionScript perspective. I could just about follow the Smalltalk code listings, identify the early OOP features and appreciate the ancestors of contemporary UI components. What stood out was how little things have changed in the last 20 to 30 years in OOP and GUI programming. I think the more appropriate observation is how advanced Smalltalk was for its time. Krasner and Pope’s essay is the primary resource for this post.
Model-View-Controller Implementation in Smalltalk-80
The MVC pattern facilitates the separation of concerns when developing interactive graphical applications. The logic and state of the application, how users interact with the application, and how application state is presented to the user are handled by separate elements of the MVC triad. Smalltalk-80 uses the MVC metaphor to provide built-in support for interactive application development. The idea was to provide a set of built-in user interface widgets such as buttons, menus and lists that can be plugged into a GUI application. To use these built-in UI widgets effectively, the application had to be built in accordance with the MVC metaphor. Let’s take a look at the conceptual diagram of a Smalltalk-80 MVC app.
All objects in Smalltalk communicate with each other via messages. Think of messages as a way to invoke methods in an object.
At first glance, the MVC conceptual diagram seemed a little strange. The multitude of arrows indicated more acquaintances than I’m used to seeing in an MVC diagram. Model-View and Controller-Model dependencies ran both ways. The second interesting aspect was that user input goes directly to the Controller. This is a significant change as we generally expect users to interact with UI widgets in the View. In Smalltalk-80, it looks like the raw keyboard and mouse input is fed directly to the Controller. Let’s take a quick look at how the MVC metaphor is supported in Smalltalk-80.
MVC Classes in Smalltalk-80
There are three abstract classes called Model, View and Controller. All concrete implementations of model, view and controller have to subclass these abstract superclasses. Let’s take a look at the classes (this is an abbreviated description – see Krasner and Pope for more detail).
The Model Class
The abstract superclass Model implements generic model behavior. It implements a dependency maintenance mechanism. Views can register with concrete models to become dependents and receive update messages. When a concrete model sends itself a changed message, an update message is sent to all of its dependent views automatically. This is an implementation of an Observer Pattern. The concrete model, being the subject in the pattern, doesn’t explicitly know about its views.
The View Class
The abstract superclass View implements generic view behavior. The built-in UI Widgets subclass View (e.g. StandardSystemView and TextEditorView). Views can be nested to develop a complex user interface. For example, the StandardSystemView (i.e. window) contains a sub view (child view) called TextEditorView in the figure below.

A text editor built using UI widgets showing nested views and corresponding controller (from Krasner and Pope)
Each view can have one model and one controller. The built-in UI Widgets have a pre-specified default controller class to implement its default behavior (TextEditor is the default controller for the TextEditorView UI widget). To instantiate a built-in UI Widget, you need to set its model and open its window. The UI Widget will then initialize its default controller with the same model instance and register with the model as a dependent. When a window is closed, its nested views are released. When a view is released, it removes itself as a dependent form the model. All this plumbing and initialization is part of the generic code in the superclass View. If you want a UI widget to have custom behavior, you can set a custom controller for it.
The Controller Class
The abstract superclass Controller implements generic controller behavior. Each controller has a reference to one model, one controller, and a global variable called Sensor that provides an interface to the user-input devices for mouse, keyboard, and cursor interactions. The Controller superclass implements generic behavior to determine if a concrete controllers’ corresponding view has mouse focus. If the corresponding view has focus, then its controller maintains control of all user input.
The controller needs to have an explicit reference to its view because it queries the view to determine if the mouse cursor is within the views’ display rectangle. This is non-trivial as the nested view hierarchy has to be traversed. Controllers need to be well behaved, as they grab and release user input. If a view is not interactive, then its controller is a NoController instance that doesn’t take control of user input.
It is significant that only controllers, and not views, receive user input. There is a clean separation of concerns as views’ only display model data.
Key Features of the MVC implementation in Smalltalk-80
- Each built-in UI Widget is a view.
- Views can be nested.
- Each view has a corresponding controller.
- The controller queries its view to determine if it has focus to receive user input.
- The active controller (whose view has focus) receives user input.
- Controller can update the view (UI Widget) based on user input.
- Controller modifies the model based on user input.
- Views update themselves using observer synchronization with the model.
Comparing Smalltalk-80 UI Widgets (views) to Flash Components
UI Widgets in Smalltalk-80 are built according to the MVC metaphor. UI Widgets represent the view in the MVC triad. In addition to the pre-built UI widgets, Smalltalk comes with a number of controller and model classes that can be matched with UI widgets (views) to provide default behavior. For example, there is a subclass of Model called TextHolder that can serve as the model for the TextEditorView UI widget and its corresponding default controller TextEditor. Default component behavior can be overridden by plugging in a custom controller to the UI Widget.
ActionScript built-in components do not provide this much abstraction. Unlike Smalltalk, users interact directly with UI Components in Flash. How the component responds to user input is not abstracted out to a public controller class – the default action is encapsulated and implemented within the component itself. However, all AS3 components implement the IEventDisptacher interface. We can register with a UI Component to receive the same user events that the component acts on. There are several ways to prevent default behavior if the component allows it.
Unlike UI Widgets in Smalltalk, much of the controller functionality is implemented by Flash components. Essentially, the component handles its own logic and state. For example, let’s examine the class hierarchy of the AS3 Button Component.
| Package | fl.controls |
| Class | public class Button |
| Inheritance | Button LabelButton BaseButton UIComponent Sprite DisplayObjectContainer InteractiveObject DisplayObject EventDispatcher Object |
| Implements | IFocusManagerComponent |
All AS3 components subclass UIComponent whose parent classes provides functionality to manage focus, receive user events in addition to the traditional view responsibilities of coordinate transformations and nested view management.
This is the interesting dilemma when implementing the classic MVC pattern in AS3. Because UI components implement much of traditional controller functionality, does the controller have any utility in an AS3 MVC application. The best way to answer this question is to develop a simple classic MVC app in AS3.
A simple Smalltak-80 MVC application
Krasner and Pope implement a simple example application in their article to demonstrate the MVC paradigm. The application is a simple counter. The model stores the value of the counter. There is a top view (window) and three sub views: a view that displays the value of the counter (a text display area), a view that increments the counter (button), and a view that decrements the counter (button).
I’m going to develop the counter application in ActionScript using built-in Flash components while remaining true to the classic MVC implementation in Smalltalk-80. The first step is to explore support for the MVC paradigm in ActionScript.
Support for classic MVC implementation in ActionScript 3.0
Unlike Smalltalk-80, there is no explicit support for MVC development in ActionScript 3.0. That being said, let’s compare the key features of MVC implementation in Smalltalk-80 to what is available in AS3.
| Smalltalk-80 | ActionScript 3 |
| Each built-in UI Widget is a view. | We can treat each built-in UI component as a view. |
| Views can be nested. | Built-in Flash components (V3) are controls and don’t contain layout components that can be nested. Third party component frameworks such as Yahoo Astra do contain layout components. However, we can treat the Flash stage as the top view that can contain nested UI Components. |
| Each view has a corresponding controller | We can register an object (controller) to receive user events from built-in components. |
| Controller manages view focus | UI Components implement focus management. |
| The active controller receives user input. | Active component receives user input. Component can dispatch user events to registered controller object. |
| Controller can update the view (UI Widget) based on user input. | Component updates itself based on user input (default behavior). However, components can allow default behavior to be prevented through the generated event object. Registered controller can update component through the target property in the passed event object. |
| Controller modifies model based on user input | A controller object can observe component events and update model accordingly. |
| Views update themselves using observer synchronization with the model. | View can observe the model if it implements the IEventDispatcher interface. |
Let’s implement the Counter application based on these accommodations. I’m not implying that this is the best way to implement an MVC architecture in AS3. The intent is to explore the good, the bad and ugly of appropriating a classic MVC architecture into an AS3 application.
Implementing the Counter application in ActionScript 3 (using V3 components)
The first step is to define the Model, View and Controller abstract superclasses. The first limitation is that AS3 does not support abstract classes. However, as UI Components implement much of the required default behavior already, we can define pure interfaces. The model needs to implement IEventDispatcher and the controller needs to define a handler that can receive user events. All built-in components subclass UIComponent and we can consider it as the superclass for views.
CounterView is the top level view that contains the DisplayView, IncrementButtonView, and DecrementButtonView. DisplayView subclasses the Label component and registers with CounterModel to receive CHANGE events when the counter value is updated. DisplayView doesn’t respond to user input and doesn’t have a corresponding controller. In contrast, IncrementButtonView and DecrementButtonView subclass the Button component and respond to user gestures. Each button view registers a corresponding controller to receive CLICK events. The controllers modify the model based on these events.
Although model – view relationships are similar to the classic Smalltalk-80 MVC implementation, the controller relationships are radically different. The controllers essentially observe the views to catch user events. In addition, controllers don’t need to have an explicit reference to their views either. The event object that is passed to the controller when the event occurs has a reference to the UI component targeted by the event.
Take a look at the implementation in AS3 and inspect the classes. Flash V3 components are not available by default in Flex/Flash Builder. Therefore, the components have to be brought over from Flash CS3 in a swc file. This post by Josh Tynjala explains the process.
The Good, bad and ugly of the ActionScript implementation
The big difference in the AS3 implementation concerns the role of the controller. Flash UI components have taken over the role of the classic controller and relegated it to observe corresponding UI components. Does the controller play its intended role in the MVC triad, which is to serve as a strategy for handling user input? As UI components handle their own user input, the controller has become a strategy for handling change in UI components. Is there a big difference?
The good aspects
- Separated presentation is maintained.
- Controller is a strategy for handling user input (or is it?).
- Controller is essentially a command object that can be invoked by multiple views.
The disconcerting aspects
- Controller is essentially a command object – it makes sense if multiple views invoke the same command. Otherwise it may as well be tightly bound to its view.
- Event bubbling in complex nested views obsoletes the necessity to have a controller for each UI component.
- Flex and data binding may offer simpler ways of implementing separated presentation.
Form your own conclusions
The intent of this post was to lay some groundwork for the upcoming presentation patterns in this series. Exploring the utility of the classic MVC paradigm with a concrete example made a lot of issues explicit. There is a lot of heated discussion regarding the role of MVC in contemporary development with rich components. Bill posted Is MVC Obsolete? Flex, ActionScript 3.0 and the MVC Design Pattern on the issues raised by Brian Lessig’s MVC as Anti-Pattern article sometime back. The spirited discussion that followed is very relevant to this post.
References
- A cookbook for using the model-view controller user interface paradigm in Smalltalk-80 by Glenn Krasner and Stephen Pope.
- Applications Programming in Smalltalk-80: How to use Model-View-Controller (MVC) by Steve Burbeck.
- Inside Smalltalk Volume II by Wilf Lalonde and John Pugh.
Related posts:





Bill Sanders
Very nice, thank you for sharing in such a simple way.
Hi Chandima,
Extremely interesting article. The discussion on the peculiarities of ActionScript components is specially illuminating and could be extended to the whole of AS3. In fact I wanted to suggest such a discussion to be held here. After all, everything in AS3 seems to be double-connected to Views and Controllers.
Thank you for sharing your wisdom.
Curro
Hi Curro, the sophisticated event model built-into AS3 allows a totally different component architecture. I think you’ll like the next presentation pattern in the series, the autonomous view – it eliminates the controller altogether.
A very interesting read. Looking forward to the next presentation. Thank you.
Your comparison between smalltalk and AS3 is an excellent foundation for this series. I’m looking forward to the next article!
Under “The Controller Class”, you say:
Each controller has a reference to one model, one controller, and a global variable called Sensor …
should that be:
Each controller has a reference to one model, one view, and a global variable called Sensor …
presentational modelviewcontroller