Outline of Model-View paradigm as expressed in the Java libraries

Joseph Bergin, 1996

A user-centered (event driven) application can be divided into two kinds of classes- a model, implementing basic functionality and one or more views, implementing the "look and feel" of the application. The view incorporates both visual elements of the user interface, and also control mechanisms for the application. Originally this was called model-view-controller (MVC), and there were three elements, but in this simplified arrangement, the original view and controller have been combined. (MVC was originally a basic design paradigm in Smalltalk. It is discussed extensively in the Smalltalk literature. )

As an example, in a spreadsheet program built with the model-view methodology, the model would be a set of basic equations defining the relationships between cells in the spreadsheet. There is no visual or control mechanism. However, the class implementing the model provides getter and setter methods for all important model parameters (variables). Getter methods get information from an object--usually just the values of instance variables, but more generally, any pertinent information. Setter methods give information to the object--often just new values for instance variables.

In Java, a model (or part of a model) is a class that extends the Observable class. A number of the methods will be discussed below.

To continue the example, a view in the spreadsheet program might be the normal rows and columns view that we normally associate with a spreadsheet, together with a number of buttons and text entry fields for giving commands. Another view might be a graphical view of part or all of the spreadsheet, such as a bar-chart or pie-chart. The different views might be visible simultaneously in different frames, or alternately visible as appropriate to the application. The views can run in separate threads if needed.

In Java, a view is a class that implements the Observer interface. As such it must implement the update method:

public void update(Observable 0, Object arg);

This method will be called by a model object whenever the model changes as discussed below.

The way that this system works is as follows. The programmer creates a model and at least one view. The model object is constructed first and then the views. Each view "registers" with the model by sending it the addObserver message. The model keeps a list of all registered views. A view can also de-register if appropriate.

When a model changes, either because of internal computations, or because an external agent has called one of its setter methods, it sets its own member variable "changed" to true and executes its method notifyObservers. This latter function sends the notify message to all registered views with a reference to the changed model, and an additional reference parameter that can be an object of any type.

When a view gets the notify object, it can use the passed object to decide what to do. It usually polls the model (calls getter methods of the model), to determine if information important to the view has changed. If so, it updates the display as appropriate. A view can also query the model as to whether it has changed by sending it the hasChanged message. If true is returned, the view can query for values and update itself as needed.

User control is achieved when the user manipulates one of the control components of the view. This component sends messages to the model (setter methods), that cause the model to update and start the notify process in motion.

Notice that several views can be kept synchronized with this mechanism. It is also relatively easy to add new views to an application, since the underlying model generally doesn't need to be modified to do so. It is also somewhat easier to update the model for new functionality, since the interface and the functionality are kept separate.

More than anything, however, the model-view paradigm is just a way of thinking about user-centered software that gets us to clearly separate interface elements from functionality elements. It doesn't depend on a framework, for the necessary elements can be quite easily built in C or other languages. It leads to enhanced portability (of the model part at least) because system specific user-interface elements are not mingled with the basic functionality. The spreadsheet applet on my Java page (Start at my home page http://csis.pace.edu/~bergin/ and follow the Java links.) was organized using model-view ideas, but without using the Observer-Observable framework of the Java libraries. The source code is available for reading from the Applet page.

In Java you can actually think of a Model as a collection of observables rather than a single one. This can give you finer grained control over your application. Each observable in a model can then have its own observers. Each cell in a spreadsheet could be an observable with its own views. Since Java is a single inheritance language (of classes, anyway), it is a bit of a restriction that models must inherit from the Observable class. The tradeoff, however, is that all of the scaffolding of registering observers and notifying them is handled by the Obserable superclass and doesn't need to be implemented for each model.

The above is discussed briefly in Java in a Nutshell (David Flanagan, O'Reilly & Associates, 1996, pg. 343-4) and more extensively in On to Java (Winston & Narasimhan, Addison-Wesley, 1996, pg. 239ff).