Observer and Observable

A classic introduction to using Java's Observer and Observable classes in an MVC architecture

Here's the problem: You're designing a program that will render data describing a three-dimensional scene in two dimensions. The program must be modular and must permit multiple, simultaneous views of the same scene. Each view must be able to display the scene from a different vantage point, under different lighting conditions. More importantly, if any portion of the underlying scene changes, the views must update themselves.

None of these requirements presents an insurmountable programming challenge. If the code that handles each requirement had to be written de novo, however, it would add significant work to the overall effort. Fortunately, support for these tasks is already provided by the Java class library in the form of interface Observer and class Observable--both inspired, in part, by the requirements of the MVC architecture.

The Model/View/Controller (MVC) architecture

The Model/View/Controller architecture was introduced as part of Smalltalk, a popular object-oriented programming language invented by Alan Kay. MVC was designed to reduce the programming effort required to build systems making use of multiple, synchronized presentations of the same data. Its central characteristics are that the model, the controllers, and the views are treated as separate entities, and that changes made to the model should be reflected automatically in each of the views.

In addition to the program example described in the opening paragraph above, the Model/View/Controller architecture may be used for projects such as the following:

  • A graph package that contains simultaneous bar-chart, line-chart, and pie-chart views of the same data.
  • A CAD system, in which portions of the design can be viewed at different magnifications, in different windows, and at different scales.

Figure 1 illustrates the MVC architecture in its most general form. There is one model. Multiple controllers manipulate the model; multiple views display the data in the model, and change as the state of the model changes.

The MVC Architecture
Figure 1. The Model/View/Controller architecture

Benefits of MVC

The Model/View/Controller architecture has several benefits:

  • There is a clearly defined separation between components of a program -- problems in each domain can be solved independently.
  • There is a well defined API -- anything that uses the API properly can replace either the model, the view, or the controller.
  • The binding between the model and the view is dynamic -- it occurs at run time, rather than at compile time.

By incorporating the MVC architecture into a design, pieces of a program can be designed separately (and designed to do their job well) and then bound together at run time. If a component is later deemed to be unsuitable, it can be replaced without affecting the other pieces. Contrast that scenario with the monolithic approach typical of many quick-and-dirty Java programs. Often a frame contains all of the state, handles all events, does all of the calculations, and displays the result. Thus, in all but the simplest of such systems, making changes after the fact is not trivial.

Defining the parts

The model is the object that represents the data in the program. It manages the data and conducts all transformations on that data. The model has no specific knowledge of either its controllers or its views -- it contains no internal references to either. Rather, the system itself takes on the responsibility of maintaining links between the model and its views and notifying the views when the model changes.

The view is the object that manages the visual display of the data represented by the model. It produces the visual representation of the model object and displays the data to the user. It interacts with the model via a reference to the model object itself.

The controller is the object that provides the means for user interaction with the data represented by the model. It provides the means by which changes are made, either to the information in the model or to the appearance of the view. It interacts with the model via a reference to the model object itself.

At this point a concrete example might be helpful. Consider as an example the system described in the introduction.

3D Visualization System
Figure 2. Three-dimensional visualization system

The central piece of the system is the model of the three-dimensional scene. The model is a mathematical description of the vertices and the faces that make up the scene. The data describing each vertex or face can be modified (perhaps as the result of user input or a scene distortion or morphing algorithm). However, there is no notion of point of view, method of display (wireframe or solid), perspective, or light source. The model is a pure representation of the elements that make up the scene.

The portion of the program that transforms the data in the model into a graphical display is the view. The view embodies the actual display of the scene. It is the graphical representation of the scene from a particular point of view, under particular lighting conditions.

The controller knows what can be done to the model, and implements the user interface that allows that action to be initiated. In this example, a data entry control panel might allow the user to add, modify, or delete vertices and faces.

Observer and Observable

The Java language supports the MVC architecture with two classes:

  • Observer: Any object that wishes to be notified when the state of another object changes.
  • Observable: Any object whose state may be of interest, and in whom another object may register an interest.

These two classes can be used to implement much more than just the MVC architecture. They are suitable for any system wherein objects need to be automatically notified of changes that occur in other objects.

Typically, the model is a subtype of Observable and the view is a subtype of Observer. These two classes handle MVC's automatic notification function. They provide the mechanism by which the views can be automatically notified of changes in the model. Object references to the model in both the controller and the view allow access to data in the model.

Observer and Observable functions

The following are code listings for the observer and observable functions:


  • public void update(Observable obs, Object obj)
    Called when a change has occurred in the state of the observable.


  • public void addObserver(Observer obs)
    Adds an observer to the internal list of observers.
  • public void deleteObserver(Observer obs)
    Deletes an observer from the internal list of observers.
  • public void deleteObservers()
    Deletes all observers from the internal list of observers.
  • public int countObservers()
    Returns the number of observers in the internal list of observers.
  • protected void setChanged()
    Sets the internal flag that indicates this observable has changed state.
  • protected void clearChanged()
    Clears the internal flag that indicates this observable has changed state.
  • public boolean hasChanged()
    Returns the boolean value true if this observable has changed state.
  • public void notifyObservers()
    Checks the internal flag to see if the observable has changed state and notifies all observers.
  • public void notifyObservers(Object obj)
    Checks the internal flag to see if the observable has changed state and notifies all observers. Passes the object specified in the parameter list to the notify() method of the observer.

Next we'll take a look at how to create a new Observable and Observer class, and how to tie the two together.

Extend an observable

A new class of observable objects is created by extending class Observable. Because class Observable already implements all of the methods necessary to provide the desired behavior, the derived class need only provide some mechanism for adjusting and accessing the internal state of the observable object.

In the ObservableValue listing below, the internal state of the model is captured by the integer n. This value is accessed (and, more importantly, modified) only through public accessors. If the value is changed, the observable object invokes its own setChanged() method to indicate that the state of the model has changed. It then invokes its own notifyObservers() method in order to update all of the registered observers.

Listing 1. ObservableValue

import java.util.Observable;
public class ObservableValue extends Observable
   private int n = 0;
   public ObservableValue(int n)
      this.n = n;
   public void setValue(int n)
      this.n = n;
   public int getValue()
      return n;

Implement an observer

A new class of objects that observe the changes in state of another object is created by implementing the Observer interface. The Observer interface requires that an update() method be provided in the new class. The update() method is called whenever the observable changes state and announces this fact by calling its notifyObservers() method. The observer should then interrogate the observable object to determine its new state, and, in the case of the MVC architecture, adjust its view appropriately.

In the following TextObserver listing, the notify() method first checks to ensure that the observable that has announced an update is the observable that this observer is observing. If it is, it then reads the observable's state, and prints the new value.

Listing 2. TextObserver

import java.util.Observer;
import java.util.Observable;
public class TextObserver implements Observer
   private ObservableValue ov = null;
   public TextObserver(ObservableValue ov)
      this.ov = ov;
   public void update(Observable obs, Object obj)
      if (obs == ov)

Tie the two together

A program notifies an observable object that an observer wishes to be notified about changes in its state by calling the observable object's addObserver() method. The addObserver() method adds the observer to the internal list of observers that should be notified if the state of the observable changes.

The example below, showing class Main, demonstrates how to use the addObserver() method to add an instance of the TextObserver class (Listing 2) to the observable list maintained by the ObservableValue class (Listing 1).

Listing 3. addObserver()

public class Main
   public Main()
      ObservableValue ov = new ObservableValue(0);
      TextObserver to = new TextObserver(ov);
   public static void main(String [] args)
      Main m = new Main();

How it all works together

The following sequence of events describes how the interaction between an observable and an observer typically occurs within a program.

  1. First the user manipulates a user interface component representing a controller. The controller makes a change to the model via a public accessor method -- which is setValue() in the example above.
  2. The public accessor method modifies the private data, adjusts the internal state of the model, and calls its setChanged() method to indicate that its state has changed. It then calls notifyObservers() to notify the observers that it has changed. The call to notifyObservers() could also be performed elsewhere, such as in an update loop running in another thread.
  3. The update() methods on each of the observers are called, indicating that a change in state has occurred. The observers access the model's data via the model's public accessor methods and update their respective views.

Observer/Observable in an MVC architecture

Now let's consider an example demonstrating how observables and observers typically work together in an MVC architecture. Like the model in the ObservableValue (Listing 1) the model in this example is very simple. Its internal state consists of a single integer value. The state is manipulated exclusively via accessor methods like those in ObservableValue. The code for the model is found here.

Initially, a simple text view/controller class was written. The class combines the features of both a view (it textually displays the value of the current state of the model) and a controller (it allows the user to enter a new value for the state of the model). The code is found here.

By designing the system using the MVC architecture (rather than embedding the code for the model, the view, and the text controller in one monolithic class), the system is easily redesigned to handle another view and another controller. In this case, a slider view/controller class was written. The position of the slider represents the value of the current state of the model and can be adjusted by the user to set a new value for the state of the model. The code is found here.

About the author

Todd Sundsted has been writing programs since computers became available in desktop models. Though originally interested in building distributed object applications in C++, Todd moved to the Java programming language when Java became the obvious choice for that sort of thing.

This story, "Observer and Observable" was originally published by JavaWorld.

Copyright © 1996 IDG Communications, Inc.