Behavioral Patterns  «Prev  Next»
Lesson 5Observer: motivation
ObjectiveDefine the Motivation of the Observer pattern.

Observer Pattern Motivation

Motivation for the Observer Pattern

Like many other patterns, Observer is also seen outside of software engineering. For instance, suppose a lot of a bookstore customers are waiting for the latest Anne Rice novel to arrive. What's more efficient?
  1. To have each of several dozen customers come visit the store every day and bother the clerk?
    (Has it come in yet? No, it has not come in yet. Come back tomorrow.) OR
  2. to have the clerk take people's names and phone numbers on a list and call them all back when the book arrives?

Obviously it is more efficient for the clerk to keep a list. That is really all the Observer pattern is, the changing object is maintaining a list and promising to notify customers on the list when it changes.

Register and receive Notifications

The observer design pattern enables a subscriber to register with and receive notifications from a provider. It is suitable for any scenario that requires push-based notification. The pattern defines a provider (also known as a subject or an observable) and zero, one, or more observers. Observers register with the provider, and whenever a predefined condition, event, or state change occurs, the provider automatically notifies all observers by calling one of their methods. In this method call, the provider can also provide current state information to observers.

Have you ever used a program that shows you two editable views of the same data, such as a (WYSIWYG) what you see is what you get and a structural view of a document? When you edit one of the views, the other updates automatically and instantaneously.
Have you ever wondered how such a feature is programmed?
  1. When you type text into one of the windows, how does it show up in the other window?
  2. What happens if you have a third view of the same information?
The key to implementing this behavior is the (MVC) model/view/controller architecture.
  1. Model: One object, the model, holds the information in some data structure, (for example) an array of numbers, a tree or Javabean. The model has no visual appearance at all and just holds the raw data.
  2. View: Several other objects, the views, draw the visible parts of the data, in a format that is specific to the view. For example, the table view displays numbers in a table. The graph view displays the same numbers in a bar chart.
  3. Controller: Finally, each view has a controller, an object that processes user interaction. The controller may process mouse and keyboard events from the windowing system, or it may contain user interface elements such as buttons and menus.

Changes in State of another Object in a System

It is not uncommon for one object in a system to want to know about changes in the state of another object in the system.
For instance:
  1. A fax modem program should know when the serial port state changes, indicating an incoming call.
  2. A document needs to know when the state of the FontDialog object changes from Times to Helvetica.

In the case of the course project, vehicle queues need to know when the state of the light changes. The VehicleQueue could run a thread that keeps checking the light, but it is simply too much to ask an object to check constantly the state of some other object, just because it wants to know when the object changes. The solution is that the changed object should take responsibility for notifying other objects that it has changed. Assuming reasonable data encapsulation has been used, the only way the object's state can be changed is by invoking methods in the object. All that is needed is a little extra code added to each method to notify other objects that it has changed. This is called the Observer pattern and a developer should use the Observer pattern when:
  1. The changes to one object imply possible changes in other objects.
  2. The object that changes does not know at compile time exactly which other objects need to be notified of its changes.

Mechanics of the Observer Pattern

When viewing data within a graphical user interface, we often would like to display data in more than one form at the same time and have all of the displays reflect any changes in that data. For example, you might represent stock price changes both as a graph and as a table or list box. Each time the price changes, we would expect both representations to change at once without any action on our part. We expect this sort of behavior because there are a number of MS Windows applications, like Excel, where we see this type of behavior occuring. Now there is nothing inherent in Windows to allow this activity and programming directly in Windows in C or C++ requires a certain amount of skill. In Java, however, we can easily make use of the Observer Design Pattern to cause our program to behave in this way. The Observer Pattern assumes that the object containing the data is separate from the objects that display the data, and that these display objects observe changes in that data. This is simple to illustrate as we see below.

The data is separate from the Graphics and List Display
The "Data" is separate from the Graphics and List Display

When we implement the Observer pattern, we usually
  1. refer to the data as the Subject and
  2. each of the displays as Observers.

Each of these observers registers its interest in the data by calling a public method in the Subject. Then, each observer has a known interface that the subject calls when the data change. We could define these interfaces as follows:

abstract interface Observer {
  //notify the Observers that a change has taken place
  public void sendNotify(String s);
}
//-----
abstract interface Subject {
  //tell the Subject you are interested in changes
  public void registerInterest(Observer obs);
}

The advantage of defining these abstract interfaces is that you can write any sort of class objects you want as long as they implement these interfaces, and that you can declare these objects to be of type Subject and Observer independent of what else they do.