MSc-IT Study Material
January 2011 Edition

Computer Science Department, University of Cape Town
| MIT Notes Home | Edition Home |

Patterns in Java

Some design patterns generally recognised as common solutions to specific problems have been adopted as part of the Java JDK and Java API. A sample of these design patterns will be analysed here in greater detail.

The Observer pattern in Java

In Java, the Observer pattern is embodied by the Observer interface and the Observable class which are part of the java.util package.

Any object that needs to send a notification to other objects should be sub-classed from class Observable, and any objects that need to receive such notifications must implement the interface Observer.

Table 8.2. Observable class methods in java.util.package

Observable MethodsDescription
addObserver(Observer o)Add the object passed as an argument to the internal record of observers. Only observer objects in the internal record will be notified when a change in the observable object occurs.
deleteObserver(Observer o)Deletes the object passed as an argument form the internal record of observers.
deleteObservers()Deletes all observers from the internal records of observers.
notifyObservers(Object arg)Call the update() method for all the observer objects in the internal record if the current object has been set as changed. The current object is set as changed by calling the setChanged() method. The current object and the argument passed to the notifyObservers() method will be passed to the update() method for each Observer object.
notifyObservers()Same but with null argument.
countObservers()The count of the number of observer object for the current object returned as an int.
setChanged()Sets the current object as changed. This method must be called before calling the notifyObservers() method.
hasChanged()Returns true if the object has been set as changed and false otherwise.
clearChanged()Reset the changed status of the current object to unchanged.


addObserver() method of the Observable class registers the Observers.

Each class that implements an Observer interface will have to have an update() method, and this method will ensure that the objects will respond to the notification of a change in the Observable object by executing the update() method:

public void update(Observable, Object)

The Observable object can indicate that it has changed, by invoking at any time notifyObservers()

Each Observer is then passed the message update() where the first argument is the Observable that has changed and the second is an optional one provided by the notification.

Example of Observer pattern using java.util

An electrocardiogram (ECG) monitor attached to a patient notifies four different devices:

  • Remote Display for the physician, to allow them to adjust the configuration settings and treatment.

  • Chart Recorder that will display the waveforms.

  • Remote Display with a patient alarm.

  • Instruments Monitor for the service personnel.

Figure 8.11. The ECG Observer

The ECG Observer

Each of the devices will perform specific operations when the events for which they have registered an interest take place. The ECG attached to the patient will notify them of changes, as they occur. The skeleton solution presented below will display messages stating the specific tasks performed by each Observer.

/*========================================================= ECG.java 

Definition of class ECG subclassed from Observable
from which Observable objects will be created. 
Demonstrates the use of methods setChanged() which will change 
the state of the ECG object, and notifyObservers() which will 
broadcast the event to the registered objects.

==============================================================*/

import java.util.*;

public class ECG extends Observable
{
    String message = "";

    public void broadcastChange()
    {
        message = "\tHeart Electrical Activity";
        setChanged();
        notifyObservers();
    }

    public String getState()
    {
        return message;
    }
}

//class



/*=============================================================

TheObserver.java

Definition of class TheObserver from which Observer objects will 
be created.

The class implements the Observer interface and thus must define 
the method update() which will be executed when the objects of 
class TheObserver are notified.

==============================================================*/

import java.util.*;
import java.io.*;

public class TheObserver implements Observer
{
  String name;
  String says;

  public TheObserver (String name, String says)
    {
        this.name = name;
        this.says = says;
    }

    public void update(Observable O, Object o)
    {
        System.out.println(((ECG)O).getState()+
        "\n\t" + name + " : " + says+ "\n");
    }
}

//class

 
/*============================================================

PatternTest.java

Definition of program to test the Observer pattern

An object of class ECG called ecg is created, as well an array 
called observers containing the four TheObserver objects.

These objects register with the observable object ecg using method 
addObserver.

When the ecg method broadcastChange() is executed the observers 
will be notified and update themselves.

==============================================================*/

import java.util.*;

public class PatternTest {

    public static void main(String[] args) {
        ECG ecg = new ECG();
        TheObserver[] observers 
        = { new TheObserver("Physician", "Adjust Configuration"),
            new TheObserver("Remote Display","Monitor Details"),
            new TheObserver("Chart Recorder", "Draw ECG WaveForm")
            new TheObserver("Service Personnel", "Monitor Instruments")};

        for (int i = 0; i < observers.length; i++)
            ecg.addObserver(observers[i]);

      ecg.broadcastChange();
   }
}

The Observer pattern as part of the Java API

An example of the application of the Observer pattern of the Java API is the Java model of event handling using listeners. Graphical User Interface (GUI) components from the Java Abstract Windowing Toolkit (AWT) such as buttons, text fields, sliders, check boxes, and so on, are managed in this way. The observer objects implement a listener interface (e.g., the ActionListener, WindowListener, KeyListener etc.). When any of the components changes state, the listeners are notified that a change has occurred. The listener decides what action should be taken as a result of the change. To tell a button how the events it generates should be responded to, the button's addActionListener() method is called, passing a reference to the desired listener. Every component in AWT has one addXXXListener() method for each event type that the component generates. When a button with an action listener is clicked, the listener receives an actionPerformed() call which will contain the instructions that need to be performed in response to the event. The actionPerformed() method must be defined as part of implementing the listener interface

The Model-View-Controller pattern

This pattern is a specialised version of the Observer pattern, which was introduced in the Smalltalk language as a way of structuring GUI applications by separating the responsibilities of the objects in the system. The user interface consists of a View, which defines how the system should present this information to the user, and a Controller, which defines how the user interacts with the Model, which receives and processes input events. Systems analysis and design concentrates mainly on building the model representing the main classes of the application domain and the information of interest will be internally stored in object of the classes. The Model-View-Controller pattern makes it possible to associate the model with many different view/controller pairs in a non-intrusive manner without cluttering the application code. It is introduced here because it can be easily applied to the way in which Java applications using the java.awt can be structured. It provides a way for providing the application system model with a user interface. This is achieved by separating the responsibilities as follows:

The responsibilities of the Model are:

  • To provide methods that enable it to be controlled.

  • To provide a method or methods to update itself, and if it is a graphical object, to display itself.

The Controller carries out the following series of actions:

  • The user causes an event such as clicking the mouse over a button.

  • The event is detected.

  • A method to handle the event is invoked.

  • A message will be sent to the model.

  • The update method within the model will change the data within the model.

  • A message will be sent to the view update the user interface, to, for example, redraw the image.

The View performs the following:

  • Initially displays the model when the window is created, and every time it is resized.

  • When the event handler detects a change (e.g., responds to a click of a button) it sends a message to redraw the screen.

  • The View enables the updated information from the model to be displayed.

Abstract factory facilities in Java

To make the creational process more versatile, object-oriented language facilities that provide for customisation should be used. The JDK has facilities to customise graphics and to internationalise programs and applications.

Graphics related platform characteristics

One of the problems of having a portable Abstract Windowing Toolkit is that the appearance and positioning of the objects may differ from one platform to another. To ensure that the graphical display is similar wherever the application may be ported, we should be able to adjust the View accordingly.

The ToolKit and FontMetrics classes may be used to help create a Concrete Factory that will create the Concrete Product:

Figure 8.12. Java output of screen and font information

Java output of screen and font information

The ToolKit class provides information regarding screen resolution, pixels, available fonts, and FontMetrics can help supply information concerning font measurements for every AWT component. Below is a program listing showing how some screen and font information can be obtained. Figure 8.12, “Java output of screen and font information”, shows an example of some output obtained from the program.

/*=============================================================

Sysinfo.java  

program for finding out details of the display using the 
java.awt Toolkit class 

The program creates a Toolkit class object theKit, and then uses 
the Toolkit methods:

getDefaultToolkit, getScreenResolution, getScreenSize and getFontList.

===============================================================*/

import java.awt.*;

public class Sysinfo
{
    public static void main(String[] args)
    {
        Toolkit theKit = Toolkit.getDefaultToolkit();
        System.out.println("\nScreen Resolution: " +
          theKit.getScreenResolution() + " dots per inch");
        Dimension screenDim = theKit.getScreenSize();

        System.out.println("Screen Size: " + screenDim.width 
          + " by " + screenDim.height + " pixels ");

        String myFonts[] = theKit.getFontList();
  
        System.out.println("\nFonts available on this platform: ");

        for (int i = 0; i < myFonts.length; i++)
          System.out.println(myFonts[i]);

    return;
  }
}

Java facilities for internationalisation of applications (displaying all user visible text in the local language, using local customs regarding dates, monetary displays etc.) are available from java.util package using the ResourceBundle class and its subclasses.

Composite patterns in Java

HCI classes for creating GUI applications are used in almost every interactive application. Much of these GUI classes adhere to some form of Composite pattern, and the Java AWT is no exception. Here, containers are components which can hold other components. Each component knows how to draw itself on the screen; containers, however, will defer some of their drawing functionality to the components that they contain.

Figure 8.13.  java.awt GUI components containers and layout managers

java.awt GUI components containers and layout managers

Layout ManagersDescription
FlowLayoutPlaces components in successive rows in a container, fitting as many on each row as possible, and starting on the next row as soon as a row is full. This works in much the same way as a text processor placing words on a line. Its primary use is for arranging buttons, although it can be used with components. It is the default layout manger for Panel and Applet objects
BorderLayoutPlaces components against any of the four borders of the borders of the container and in the centre. The component in the centre fills the available space. This layout manger is the default for objects of the Window, Frame, Dialog, and FileDialog classes
CardLayoutPlaces components in a container, one on top of the other – like a deck of cards. Only the top component is visible at any one time.
GradLayoutPlaces components in the container in a rectangular grid with the number of rows and columns that you specify.
GridBagLayoutThis places the components into an arrangement of rows and columns, but the rows and columns can vary in length. This is a complicated layout manager with a lot of flexibility for controlling where components are placed in a container.

In Java, these are embodied by the AWT Component and Container class, and the layout manager classes. A Window can be divided into Panels, and each Panel can be treated as an individual component within another layout at a higher level.