Krasner Pope 88
Krasner Pope 88
Krasner Pope 88
Paradigm in Smalltalk-80
Glenn E. Krasner
Stephen T. Pope
Introduction
The user interface of the Smalltalk-80'" programming environment (see references. [Goldberg 831) was developed using a
particular strategy of representing information. display. and
control. This strategy was chosen to satisfy two goals: ( 1 ) to
create the special set of system components needed to support a
highly interactive software development process: and (2) to
provide a general set of system components that make it possible for programmers to create portable interactive graphical
applications easily.
In this anicle we assume that the reader has a basic
knowledge of the Smalltalk-80 language and programming environment. Interested readers nor familiar with these are
referred to [Goldberg and Robson 831 and [Goldberg 831 for introductory and tutorial material.
Model-View-Controller (MVC) programming I S the application of this three-way factoring. whereby objects of different
classes take over the operations related to the application
domain (the modell. the display of the application's state (the
view). and the user interaction with the model and the view (the
controller). In earlier Smalltalk system user interfaces. the tools
that were put into the interface tended to consist of arrangements of four basic viewing idioms: paragraphs of text. lists of
text (menus). choice "buttons." and .graphical forms (bit- or
pixel-maps). These tools also tended to use three basic user interaction paradigms: browsing. inspecting. and editing. A goal
of the current Smalltalk-80 system was to be able to define user
interface :omponents for handling these idioms and paradigms
once. and share them among all the programming environment
tools and user-written applications using the methodology of
MVC programming.
We also envisioned that the MVC methodology would allow
programmers to wri~ean application model by first defining neu,
classes that would embody the special application domainspecific information. They would then design a user interface to
it by laying out a composite view (window) for it by "plugging
in" instances taken from the pre-defined user interface classes.
This "pluggability" was desirable not only for viewing idioms.
but also for implementing the controlling (editing) paradigms. AIthough certainly related in an interactive application. there is an
advantage to being able to separate the functionality between
how the model is displayed. and the methods for interacting with
it. The use of pop-up versus fixed menus. the meaning attached to
keyboard and mouse/function key. and scheduling of multiple
views should be choices that can be made independently of the
model or its view(s). They are choices that may be left up to the
end user where appropriate.
Aurhors Address.
TO address the issues outlined above. the Model-View-Contro]ler metaphor and its application structuring paradigm for thinking about (and implementing) interactive application corn-
.,..
Models
Broadcasting Change
The model of an application is the domain-specific software
simulation or implementation of the application's central structure. This can be as simple as an integer (as the model of a
counter) or string (as the model of a text editor). or it can be a
complex object that is an instance of a subclass of some
Smalltalk-80 collection or other composite class. Several examples of models will be discussed in the following sections of
this article.
Views
In this metaphor, views deal with everything graphical: they
request data from their model, and display the data. They contain not only the components needed for displaying but can
also contain subviews and be contained within superviews. The
superview provides ability to perform graphical transformations. windowing. and clipping between the levels of this subview/superview hierarchy. Display messages are often passed
from the top-level view (the standard system view of the application window) through to the subviews (the view objects
used in the subviews of the top-level view).
Dependents
To manage change notification. the notion of objects as dependetlts was developed. Views and controllers of a model are
registered in a list as dependents of the model, to be informed
whenever some aspect of the model is changed. When a model
has changed, a message is broadcast to notify all of its dependents about the change. This message can be parameterized
(with arguments). so that there can be many types of model
change messages. Each \.ie\\ or controller responds to the appropriate model changes in the appropriate manner.
An Implementation of Model-View-Controller
The Smalltalk-80 implementation of the Model-View-Controller metaphor consists of three abstract superclasses named
Model, Wen,, and Conridlel: plus numerous concrete subclasses. The abstract classes hold the generic behavior and state of
the three parts of MVC. The concrete classes hold the specific
state and behavior of the application facilities and user interface components used in the Smalltalk-80 system. Since our
primary set of user interface components were those needed for
the system's software development tools. the most basic concrete subclasses of Model. View. and Controller are those that
deal with scheduled views. text. lists of text. menus. and
graphical forms and icons.
Class Model
The behavior required of models is the ability to have dependents and the ability to broadcast change messages to their
pay
interest
Figure 3. Message-sending and dependency updating for an example from the FinancialHis~oryapplication
-23,
1 ,-I
= "Normal" message-passing
= Dependents changed/update messages
Window1n_eTranstorm;1t1011
un1c.n rcpiesciio
,......, ..
(translation and scaling) between that view's coordinate system
and that of its superview. In addition. there is a default protocol
in View for adding and removing subvieus. as well as a
protocol for changing the transformations. This allows views
consisting of many subviews to be pieced together flexibly and
simply.
The third type of behavior in class View is that which relates
to displaying. Because subclasses of Vieu are assumed to use
display objects to actually do their displaying (Forms. Pens.
Lines. or instances of other graphical classes). View only suppons generic displaying behavior. In particular. there is no instance variable for display objects. Class View assumes that the
top level of a subview structure displays on some medium
(typically the display screen).
Views therefore cache the transformation from their own internal coordinate system to the display's coordinate system (i.e., the
composition of the view's transformation and all of its
superviews' transformations). so that it is faster to get from a
view's internal space to display space. View also has instance
variables insetDisp1a~Bo.v.the clipping rectangle within which
the view may display without overlapping other views: borderWidrh and border-Color; to define the (nonscaled) borders between a view and its superview: insidecolor. to detine the color
(if any) with which a view colors its insetDisplayBox before actually displaying its contents: and bo~mdingBo-r.to describe the
extent of display objects within the view's coordinate system.
By default. the message model: anobject, when sent to a
view. initializes the view's controller to be a new instance of
the view's default controller class. It establishes artObjecr as
the model for both the view and the controller. and establishes
the view as a dependent of the model. This one message is typically sufficient for setting up the MVC structure.
The message release, used when closing a hierarchy of
views (i.e.. the subviews of one top-level window), gives the
programmer the opportunity to insert any finalization activity.
By default, release breaks the pointer links between the view
and controller. The message release also removes the view
from its model's dependents collection. breaking reference circularities between them.
LL,L
Class Controller
It is a controller's job to handle the control or manipulation
(editing) functions of a model and a particular view. In particular. controllers coordinate the models and views with the
input devices and handle scheduling tasks. The abstract superclass Controller contains three instance variables: nrodel. rie.lc..
and sensor. the last of which is usually an instance of class
Inputsensor representing the behavior of the input devices.
Because the interpretation of input device behavior is very
dependent on the particular application. class Controller implements almost none of this behavior. The one such behavior that
is implemented is the determination of whether or not the controller's view contains the cursor.
Class Controller does include default scheduling behavior. It
takes the point of view that only one controller is to bq active
at a time: that is. only one controller at a time mediates user
Graphics-Dtsclay Ob~ecr
Graohlcs-Paths
Graph~cs-V~ers
Graphtcs-Ea~tors
Graphtcs-Su~oor:
Kernel-Objects
Kernel-Classes
value: 0
dependents:
OrderedCollection (a Counterview)
Counter
4'
model: a Counter'
view: a CounterViewD
yellowBunonMenu: a PopUpMenu
yellowBunonMessages (increment decrement)
sensor: an InputSensor'
CounterController
30
a Counter
controller: a CounterController
suoerview: a StandardSvstemView
b i e s : ~ r d e r e d ~ o l l e o) n
insetDis~layBox: 421@34 corner: 569@104
borderwidth: 2@2 corner: 2@2
bordercolor: a Form
insidecolor: a Form
Counterview
Interaction devices
(mouse, keyboard)
PleasQ t y p e a file n a m e :
The classes View and Controller. along with the other abstract
classes. provide the framework for views and controllers in the
Smalltalk-80 implementation of the Model-View-Controller
metaphor. The system also contains various subclasses of View
and Controller that provide the pieces of user interface
functionality required by interactive applications. These. user
interface components include menus. text. and forms. These
components are pieced together to form the standard system
views of the Smalltalk-80 application development environment. and can be reused or subclassed for system applications.
They form the kernel of the component library of model-building tools and user interaction components that can be easily
'-pulled off the shelf' and "plugged" together to create interactive applications. We list some of them here. but in most cases
we only use the names of the subclasses of View: it is assumed
that each is used with one or more appropriate Controller subclasses.
SttYtchli'en. and Listl'ierc are two subclasses of View that
provide static or dynamic menu behavior. SwitchViews are
used. for example. in the instance/class switch of the system
browser or the iconic menu of the form editor. They behave as
a switch; they can either be on or off. and when the user clicks
the mouse button on them. they will notify their model. These
are typically used as menus of text or forms. or "buttons."
?, ListView is a scrolling menu of text items. such as those
used in the upper four subviews of the system browser (shown
in Figure 1 1 J. It will inform its model when the user has made
a new selection in the list. Figure 5 shows examples of the use
of subclasses of SwitchViews (in the iconic menu of [he FormEditor, the paint program) and Listviews (in the Browser's
catcgory list subview).
Ptmlprer-s and Cot1firmei.s are simple views that can be used
for eliciting user input. They are started up by giving them a
string for their query or prompt. and can return either a string
value (in the case of Prompters) or a Boolean value (in the case
of Confirmers).
Because they can be considered as belonging more to the
exit ~ r o i e c :
aste
mad reader
aracoo
move
hardcopy
ardcooy below
save
TopView =
StandardSystemVicw
,-
up*anaDlas '
box
self InserD age'"
top
box top.
bottom
box bO 'OPY
1.R
box Iaft.
asre
ngnt
box nght. ao ~t
pnnt I C
-+
(5
( pitcnscals
rowser
workspace
file 1st
file taltor
Subview =
TextEdi torview
Controller =
TextEdi tor (manages
the w o - u v menu)
31
~ l l. ~
l o~ CCo ~
r i ~r rlo f/ /~f ~~ :
mentioned earlier: ~ f ~ l l . ~ ~ ~ . ~ ~ c and
and the class 111pitrSe1is01.
that is used for monitoring user inpui.
There is a global object called Scrisor- ihat ia the sole instance
of the class Inputsensor. I t is used to model the user's input
devices such as the mouse and the keyboard. One can send
query messages to Sensor such as anyButtonPressed. or one
can wait for a user action ~ . i i hmessages such as waitBlueButton. One need normally never refer to Sensor. since it is
used in the iniplementation of the more basic controller classes.
but many types of special user interface componenls. especially those that track the mouse directly (for rubber-band lines. for
example). use it.
C&or
mroect
eferencer
remove
Dicr~onay
Dictionwylns
nnt Ir
DisviayMeoi~
OispiiyScan
~rapnio-views
I
boroenng
....r*ro.
C,
ext t x.
width
height * ax en1 y.
011set * a oint.
b l t l * aEi map
instance/class
switches
32 JOOP AugustSeptember 1988
~ d d view
e
[zed inspecrorb tor i o i l i p ~ i . . \O L ~ , C . L > y u C , , ..., .,. . ..,-.. selves or application-specific classes such as event lists.
tions
Workspaces
Browsers
The workspaces in the system are StringHolderView/StringHolder controller combinations installed as the single subview
of a Standardsystemview. Their model is an instance of StringHolder. which merely holds onto an instance of Text, a String
with formatting information. The menu messages implemented
by StringHolderController correspond to the basic text editing
and Smalltalk-80 code evaluation commands as shown in the
menu in Figure 9.
Inspectors
The inspectors in the system are implemented as two views.
A ListView contains the instance variable list (left side), and a
TextView displays the value of the selected instance variable
(right side). An instance of Inspectorview serves as their common superview. and an instance of Standardsystemview serves
as its superview for scheduling purposes. The model for these
views is an instance of Inspector.
Inspectors can be used to view any object. A separate class,
Inspector: serves as the intermediary or filter for handling access to any aspects of any object. As a result, no extra protocol
is needed in class Object. Using intermediary objects between
views and -'actual" models is a common way to further isolate
the viewing behavior from the modeling application.
It is possible to build a more appropriate interactive interface
to composite objects by subclassing the inspector for use with
Selected Method
Code View
awn
fauwz,
---------------
;a.ita
undo
COPY
cut
p
.
,
t
.
00 It
pnnt it
Receiver Object
Inspector
Method temporary
variable Inspector
33
Figure 13. Setup message for the class list view in the browser using a pluggable SelectionlnListView
classListView c SelectionlnListView
on: aBrowser
aspect: #className
change: #className:
list: #classList
menu: #classMenu
initialselection: #className.
in: myAreaRectangle
borderwidth: 1
item select~ondefin~tions.
In some sense. this is an engineering trade-off. because i t has
iesb tlexibilit! than entirely new class definitions and can lead
to having controller information in the model,. It does.
however. reduce the number of different things the developer
needs to do to get an application together. as well as the number of different classes needed.
.An example of the use of pluggable views is the implementation of the system browser list subviews. The original implementation had a special subclass of Listcontroller for each of the list
subviews. Each of these classes had its own definition of the
menus and messages to send when the menu item was selected.
and its own message to send when a new list item was selected.
The current pluggable implementation has four instances of the
same class. SelectionInListController. with parameters that represent the messages to be sent to the model when the selection
changes. and to create an appropriate menu when the proper
mouse button is pressed. The Browser model knows about the
four local menus and receives the corresponding messages.
The use of the setup message for adding a pluggable
SelectionInListView to a composite.view is demonstrated in the
Figure 13. This code segment comes from the actual view initialization for the Browserview. It defines a SelectionInListView in the subview area described by the rectangle mpAreaRectangle. It uses the messages and the menu referred to in the
figure.
The pluggability of SelectionInListViews is afforded by the
class message shown here. namely on:aspect:change:list:rnenu:initialSelection:. The message addSubView:in:borderWidth: is defined in class View for the composition of complex viewlsubview layouts. Messages of this type are the
essence of subview pluggability and examples of their use and
utility are available through out the system's user interface
classes. Several other classes of plugpable subviews implement
similar instantiation lplri~gingimessages.
Another example of a pluggable view is the text view used in
many system views. In this case. one wants to plug a text editor
subview into a view and tell it the messages needed for it to access its new text contents. to set its model's text. and to display
its menu. The message that is implemented in the class CodeVew for this is on:aspect:change:menu:initialSelection:
(note the similarity between this and the message used above
for a pluggable SelectionInListView). The example message in
Figure 14 is the entire method used to define a FileEditor view
such as the one shown in Figure 8.
Several of the other views can be used with pluggable instantiation messages. These include the saitch views (which one
passes a label. the messages they send to determine their state
~ n drespond to being pressed). and confirmers and prompters
cone passes them a message or prompt and they return strings
or Boolean values).
Models a n d MVC Usage
Class Object contains behavior that supports Model's
t'unctionality. i.e.. the ability for any object to have dependents. and
d 0
,c
. ,..
.. ..,
%.
. .-
35
Now define a class for the controller, along with the methods
to define the menu it uses and those that implement the menu
functions by passing them along to the model. The controller
inherits all its instance variables from its superclasses.
MouseMenuController subciass: #CounterController
instanceVariableNames: ' '
classVariableNames: ' '
poolDictionaries: ' '
category: 'Demo-Counter'
CounterController methodsfor: 'initialize-release'
initialize
"Initialize a menu of commands for changing the
value of the model."
super initialize.
self yellowButtonMenu: (PopUpMenu labels:
'Increment\Decrement' withCRs)
yellowButtonMessages: #(increment decrement)
CounterController methodsfor: 'menu messages'
decrement
"Subtract 1 from the value of the counter."
self model decrement
increment
"Add 1 to the value of the counter."
self model increment
CounterController methodsfor: 'control defaults'
isControlActive
"Take control when the blue button is not pressed."
Discussion
The code pre3ented so far is the most trivial sort of complete
blVC implementation. Suppose now that we wish to add pushbuttons to the view instead of having menu items to increment
and decrement the value of the counter. Using pluggable button
Listing 1.
CounterView MethodsFor: 'displaying'
displayview
"Display the value of the model in the receiver's view."
I box pos displayText I
box t self insetDisplayBox.
"get the view's rectangular area for displaying"
"Position the text at the left side of the area, 113 of the way down"
box origin + (4 @ (box extent y 13)).
"concatenate the components of the output string and display them"
displayText t ('value:, self model value printstring) asDisplayText.
pos
Listing 2.
"top-level view"
listview t SelectionlnListView
on: anorganization
aspect: #organization
change: #organization:
list: #organizationList
menu: #organizationMenu
initialselection: #currentcategory
textview t CodeView
on: anorganlzation
aspect: #text
change: #acceptTex!:
menu: #textMenu.
39
Figure IS.
\'leu
aCounterView borderwidth: 2.
aCounterView insideColor: Form white.
value: 0
organizationList
"return the list of organization keys (topics), the
keys of the dictionary"
?organization keys asSortedCollection
organization: acategory
"set the current category and signal that the organization text has changed"
currentcategory t acategory.
self changed: #text
addcategory
"Add a new category, prompting the user (with a FillInTheBlank) for its name"
1 newcategory I
Newcategory t FilllnTheBlank
request: 'New Category' initialAnswer: (").
newcategory =" iffrue: [?self].
organization at: newcategory put: Text new.
currentcategory c newcategory.
self changed: #organization
renamecategory
"prompt the user for a new name and rename the
current categor "
l newcategory
newcategory t FilllnTheBlank
request: 'New Category'
initialAnswer: (currentcategory).
newcategory = " ifTrue: [?self].
organization at: newcategory put: (organization at:
currentcategory).
organization removeKey: currentcategory
currentcategory t newcategory.
self changed: #organization
i"
organizationbdenu
"return the menu to be used in the topic key list"
currentcategory == nil
ifTrue: [TActionMenu ActionMenulabels: 'add
category' selectors: #(addCategory)].
TActionMenu ActionMenulabels: 'add
category\rename\removel withCRs
selectors: #(addcategory renamecategory removeCategory)
rigule
View
IU.
filth
c u d , u ~ ~ , . ,t? .
\ L~
L,..
AL.U
,.,Y,L~..=
L L
.,
". .. LV..,..-.
L L L ~ V L . ~
graph~calbuttons
val: 0
Figure 17. Organizer view showing list and text views and menus
=nan
es
Smalltalk nochanges.
rename
remove
- --'empty the change set'
~ y ~ r eSupport
%
=: Terminal Support
S: Clocks
,,::ie
ao ~t
1 I
Smailtaik changes.
'access the change
'remove all changes to a class from the
Stream removeFromChanges.
The text-related messages allow the user to query and set the
text value for the currently selected category, as shown in
Listing 3.
Organizer methodsfor: 'text'
text
"answer the text for t h e current category"
currentcategory == nil ifTrue: [?Text new].
Torganization at: currentcategory copy
acceptText: aText
"this is s e n t to accept t h e changed text from the
text subview"
currentcategory == nil ifTrue: [Tfalse].
organization at: currentcategory put: aText copy.
Ttrue
textMenu
"answer the menu u s e d in the text subview"
TActionMenu
labels: 'again\undo\copy\cut\paste\do it\print it\inspect\accept\cancel'
withCRs
lines: #(2 5 8)
selectors: #(again undo copyselection cut p a s t e
dolt printlt
inspectlt a c c e p t cancel)
The methods used to parse streams assume that special strings
arc used for separating entries from their keys and for separat-
Listing 1.
I receiveFrom amount I
"prompt the user with a FilllnTheBlank prompter"
receiveFrom t FilllnTheBlank request: 'Receive from what?'.
receiveFrom =" ifTrue: [Tse~f].
"return if he/she answers blank"
amount t FilllnTheBlank request: 'How much from', receivefrom, '?'.
amount =" iffrue: [Tself].
"read a number out of this string"
amount t Number readFrom: (Readstream on: amount).
model receive: amount from: receivefrom.
classes for the FinancialHistory example and are the bar chart
elements seen in Figure 2.
The three examples presented here show some of the sophistication possible using the Model-View-Controller paradigm
and methodology in the Smalltalk-80 system. Readers are encouraged to browse the Smalltalk-80 system interface classes
or read the other references to see many more examples of
MVC programming.
Summary
The Model-View-Controller metaphor is a way to design and
implement interactive application software that takes advantage
of modularity. both to help the conceptual development of the
applications, and to allow pieces already developed for one application to be reused in a new application.
The metaphor imposes a separation of behavior between the
48 JOOP August1Septernber 1988
actual model of the application domain. the views used for displaying the state of the model. and the editing or control of the
model and views.
We have implemented the metaphor in the Smalltalk-80 system and have used this implementation both to create the basic
programming development tools used in the system, and to
develop a diverse collection of applications.
Acknowledgements
The Smalltalk-80 Programming System and the MVC user interface paradigm were developed over several years by
numerous members of the Systems Concepts Laboratory at the
Xerox Palo Alto Research Center (PARC).
Several of our colleaques at Xerox PARC and ParcPlace Systems reviewed and contributed to this paper. We are indebted to
them for their assistance.
topview
topview
topview
topview
model: aFHModel.
borderwidth: 2.
insidecolor: Form IightGray.
label: 'Financial History'.
aBCView
11s
Inrpl~nre~r-
tobject-Oriented
Programmmg
for
Smalltalk.
hpplic;lt~on\
Dc\eloper\ b i o c ~ a t ~ o n. l%
. a ~ l a b lfrom
e
OOPST.4D. P O . Box 1565. Everett.
H'\ 98206.
Further Reading
Slsplwn T Pope. Sm.illtalL-$0 ;\ppl~car~onrBibliography. Sniollto/k-SO .Le*.slzrrrr
; I / . ParcPlacc S\steni~.September 1987.
To find out more about the uae o f the >IVC ci~,ses w ~ r h ~the
n Smallwlh-80 \ys[em. ~nterestedreaders are reierred to the r),tem ~rself.Lamp the !vlessageSet
brewers for b r o w m g all senders o f the pluggable v w r init~:diwtion messape\
can be very ~ n f o r m a t ~ v eExample\
.
o f these m ~ g h be
t found In the "plugg~np" message on:aspect:chanpe:menu:initialselection: uhich 15 ~mplemented in elas\
Codeview or the parallel mewape, In the other pluggable vleu clasbei such as
S e l e c t ~ o n l n L ~ s r V ~or
e wSwirchVie\r
u w r Interlace claaOne can also browse 311 references to the >lrnple ~nteract~ve
\e\ (auch as F~lllnTheBlanhor B ~ n a r ) C h o ~ c eor
~ . the open merrage\ for the
\ysrem'\ appllcatlon blew\. For example\ o f adv;lnced Interaction usage. looking
at ~mplemcntorro f the meshage controlActivit! L.;ln Ix ~ n \ r r u c r ~ o n ~ l .
49