Behavioral Patterns  «Prev  Next»
Lesson 7 Observer: variations
ObjectiveWrite a Time Class as an Observed Object.

Write Time Class as an Observed Object

/**
 * The TimeObserver interface serves as a contract for classes that wish to be notified when time changes.
 * Implementing this interface ensures that the class has the `timeChanged` method, which gets invoked with the new time value as an argument.
 *
 * @author Thomas Hauck
 * @version 1.0
 * @since 2023-10-31
 */
public interface TimeObserver {

    /**
     * Called to notify the implementing class that the time has changed. 
     * @param newTime The new time value, represented as an integer.
     */
    void timeChanged(int newTime);
}

Description

Interface: TimeObserver
This interface declares a single method, `timeChanged(int newTime)`, that takes an integer parameter representing the new time value. Classes implementing this interface are expected to provide a concrete implementation for this method.
Method: void timeChanged(int newTime)

Parameters:

  1. newTime: The new time value. This is an integer that the implementing class uses to update its state or carry out specific actions.

Returns:

  1. void: This method returns no value.

Purpose:

The purpose of this method is to notify the object implementing this interface that the time has changed. The exact semantics of "time" and "changed" are determined by the context in which the `TimeObserver` interface is used.

Usage:

Classes that need to be notified of time changes should implement this interface and provide a concrete implementation for the `timeChanged` method. When the time changes, this method will be invoked with the new time value, allowing the class to take appropriate actions.
There are many variations on the Observer pattern. Three of the more common variations are:
  1. To make the associated classes concrete. It is often quite easy to make the Observed class concrete, especially if you only plan on having one Observer. The main advantage of making the Observed class abstract is that different classes can share the same list management logic.
  2. To require the Observed object to pass the changed state to the Observer object's update() method.
  3. To manipulate exactly which state changes trigger notifications. It may be the case that not all changes of state are of equal interest to Observers. For instance, an object observing a word processing document may care a great deal if the user types a new letter, but not much at all if they merely scroll the screen up or down.

So far, I have implicitly assumed a multicast model for the Observed object; that is, a change to a single Observed object may result in notifications to an indefinite number of objects. Occasionally, you may want to use a unicast model that only allows a single Observer object to be registered with one Observed object at a time.

A typical observer is an object with interest or dependency in the state of the subject. A subject can have more than one such observer and each of these observers needs to know when the subject undergoes a change in its state. The subject cannot maintain a static list of such observers as the list of observers for a given subject could change dynamically. Hence, any object with interest in the state of the subject needs to explicitly register itself as an observer with the subject. Whenever the subject undergoes a change in its state, it notifies all of its registered observers. Upon receiving notification from the subject, each of the observers queries the subject to synchronize its state with that of the subject's. Thus a subject behaves as a publisher by publishing messages to all of its subscribing observers. In other words, the scenario contains a one-to-many relationship between a subject and the set of its observers. Whenever the subject instance undergoes a state change, all of its dependent observers are notified and they can update themselves. Each of the observer objects has to register itself with the subject to get notified when there is a change in the subject's state. An observer can register or subscribe with multiple subjects. Whenever an observer does not wish to be notified any further, it unregisters itself with the subject. For this mechanism to work:
  1. The subject should provide an interface for registering and unregistering for change notifications
  2. One of the following two must be true:
    1. In the pull model: The subject should provide an interface that enables observers to query the subject for the required state information to update their state.
    2. In the push model: The subject should send the state information that the observers may be interested in.
  3. Observers should provide an interface for receiving notifications from the subject.

Time Observer Interface - Exercise

In this exercise, you will write a Time class using the Observer pattern.
Time Observer Interface - Exercise