ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

A Generic MVC Model in Java A Generic MVC Model in Java

by Arjan Vermeij
07/07/2004

Model-View-Controller (MVC) is a widely used design pattern, especially popular in graphical user interface (GUI) programming. JDK 1.5 introduces parameterized types, or generics. Combining the two allows for a generic implementation of the MVC design pattern, freeing the programmer from writing code that handles the registration and notification of listeners, as well as from writing getter and setter methods for the properties of models. This article shows how this can be accomplished.

Model-View-Controller

The ideas behind MVC are quite old, developed during the 1970s. The invention of MVC is attributed to Trygve Reenskaug, who was working at Xerox PARC at the time.

The idea is to break up an application into three parts:

  • A model that holds part of the current state of the application. In this article the state of a model is represented by a set of properties. A property is implemented as a getter and a setter method, as in the JavaBeans concept.

  • A view that is, for whatever reason, interested in knowing the current state of the application. A view registers itself with a model as a listener on the model. Whenever the state of a model changes, the model notifies its registered listeners. In GUI programming, a view often does nothing more than display the state of the model through some graphical component.

  • A controller that changes the properties of the model. When and how a controller changes a property is at the discretion of the controller. In GUI programming, a controller is often something that takes input from the user; for example, a button or a text field.

To illustrate, let's introduce a simple example. The example uses two simple models, a view, and three controllers. It is implemented using JFC/Swing, and is shown in Figure 1.

Figure 1
Figure 1. A simple MVC demo

This example is not meant to be a useful application at all; its only purpose is to show how generics can help to reduce the effort involved in writing applications based on the MVC design pattern.

The example is about a hit count and a temperature. The upper half of the window shows the view. The number shows the hit count, and the color symbolizes the temperature. The bottom half of the window shows the controllers. Whenever the user clicks on the "hit!" button, the hit count is incremented. Clicking on the "it's cold!" button makes the color in the view turn blue, while clicking "it's hot!" makes the color turn red.

The example uses two models, one for the hit count and one for the temperature. Let's have a look at the code for the handling of the temperature. Here is the code for the interface implemented by the view, the listener on the TemperatureModel.

public interface TemperatureModelListener
{
  void temperatureModelChanged
     (TemperatureModel temperatureModel);
}

And here is the code for the TemperatureModel itself.

import java.util.*;

public class TemperatureModel
{
  public enum Temperature {cold, hot};

  private final List <TemperatureModelListener>
                            temperatureModelListeners;
  private Temperature temperature;

  public TemperatureModel ()
  {
    this.temperatureModelListeners
       = new ArrayList <TemperatureModelListener> ();
    this.temperature = Temperature.cold;
  }

  public void addTemperatureModelListener
     (final TemperatureModelListener temperatureModelListener)
  {
    if (! this.temperatureModelListeners.contains
             (temperatureModelListener)) {
      this.temperatureModelListeners.add
         (temperatureModelListener);
      notifyTemperatureModelListener
         (temperatureModelListener);
    }
  }

  public void removeTemperatureModelListener
     (final TemperatureModelListener temperatureModelListener)
  {
    this.temperatureModelListeners.remove
       (temperatureModelListener);
  }

  public void setTemperature (final Temperature temperature)
  {
    this.temperature = temperature;
    notifyTemperatureModelListeners ();
  }

  public Temperature getTemperature ()
  {
    return this.temperature;
  }

  private void notifyTemperatureModelListeners ()
  {
    for (final TemperatureModelListener temperatureModelListener
            : this.temperatureModelListeners) {
      notifyTemperatureModelListener (temperatureModelListener);
    }
  }

  private void notifyTemperatureModelListener
     (final TemperatureModelListener temperatureModelListener)
  {
    temperatureModelListener.temperatureModelChanged (this);
  }
}

The controllers set the value of the temperature property. The view registers itself as a temperature listener with the temperature model. You can download the complete mvc-traditional.zip code example from the Resources section at the bottom of this article.

The code uses some features introduced in JDK 1.5. First there is the declaration of the Temperature type:

enum Temperature {cold, hot}

This is an enumeration type with values cold and hot.

Then there are declarations, such as:

... List <...> ...

This is actually an instantiation of a generic type. See the next section for a brief explanation on generics.

Finally, the notifyTemperatureModelListeners method contains an unfamiliar-looking for loop of the form:

for (type variable : collection) { ... }

This for loop simply iterates over all the values in the collection.

As is immediately clear from the listing above, the TemperatureModel class is quite big, considering the simplicity of the features it supports. The HitModel class is about the same size. The TemperatureModel and HitModel classes are, as you might expect, quite similar -- both have methods to add and remove listeners, and both have methods to get and set the value of a property. It is tedious to write and maintain code that is so similar. Perhaps having only two models might not be a problem, but a serious GUI application can have lots of models.

The question is then, how we can use generics to make our life easier? Let's first explain what generics are.

New in JDK 1.5: Generics

JDK 1.5 introduces parameterized types, or generics. One of their main advantages is increased type safety by eliminating the need for class casts.

The collection classes in the java.util package have been retrofitted with generic interfaces. Thus, instead of writing:

final List stringList = new ArrayList ();

stringList.add ("hello");
// Ok, but may cause a runtime exception later on:
stringList.add (new Integer (1)); 

we can instead write:

final List <String> stringList = new ArrayList <String> ();

stringList.add ("hello");
// Not ok, compile time error:
stringList.add (new Integer (1));

For more information on generics in Java, see William Grosso's article "Generics and Method Objects" or the tutorial "Generics in the Java Programming Language" (PDF), by Gilad Bracha. You may want to consult JSR-014, which is the original proposal.

Pages: 1, 2

Next Pagearrow