The java.util.Observer
interface and java.util.Observable
class are relatively small utilities, but they provide a glimpse of a
fundamental design pattern in Java. Observers and observables are part of
the MVC (Model-View-Controller) framework. It is an abstraction that lets
a number of client objects (the observers) be
notified whenever a certain object or resource (the
observable) changes in some way. We will see this
pattern used extensively in Java’s event mechanism, which is covered in
Chapters 16 through 19. Although
these classes are not often used directly, it’s worth looking at them in
order to understand the pattern.
The Observable object has a
method that an Observer calls to
register its interest. When a change happens, the Observable sends a notification by calling a
method in each of the Observers. The
observers implement the Observer
interface, which specifies that notification causes an Observer object’s update() method to be called.
In the following example, we create a MessageBoard object that holds a String message. MessageBoard extends Observable, from which it inherits the mechanism
for registering observers (addObserver()) and notifying observers (notifyObservers()). To observe the MessageBoard, we have Student objects that implement the Observer interface so that they can be notified
when the message changes:
//file: MessageBoard.javaimportjava.util.*;publicclassMessageBoardextendsObservable{privateStringmessage;publicStringgetMessage(){returnmessage;}publicvoidchangeMessage(Stringmessage){this.message=message;setChanged();notifyObservers(message);}publicstaticvoidmain(String[]args){MessageBoardboard=newMessageBoard();Studentbob=newStudent();Studentjoe=newStudent();board.addObserver(bob);board.addObserver(joe);board.changeMessage("More Homework!");}}// end of class MessageBoardclassStudentimplementsObserver{publicvoidupdate(Observableo,Objectarg){System.out.println("Message board changed: "+arg);}}
Our MessageBoard object extends
Observable, which provides a method
called addObserver(). Each
Student object registers itself using
this method and receives updates via its update() method. When a new message string is
set using the MessageBoard’s changeMessage() method, the Observable calls the setChanged() and notifyObservers() methods to notify the
observers. notifyObservers() can take
as an argument an Object to pass along
as an indication of the change. This object—in this case, the String containing the new message—is passed to
the observer’s update() method as its
second argument. The first argument to update() is the Observable object itself.
The main() method of MessageBoard creates a MessageBoard and registers two Student objects with it. Then it changes the
message. When you run the code, you should see each Student object print the message as it is
notified.
You can imagine how you could implement the observer/observable
relationship yourself using a List to
hold the list of observers. In Chapter 16 and
beyond, we’ll see that the Java AWT and Swing event model extends this
design pattern to use strongly typed observables and observers, which are
called events and event listeners. But for now, we turn our discussion of
core utilities to another fundamental topic: I/O.