There are many variations on the Observer pattern. Three of the more common variations are:
- 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
The main advantage of making the
Observed class abstract is that different classes can share the same list management logic.
- To require the
Observed object to pass the changed state to the
- To manipulate exactly which state changes trigger notifications. It may be the case that not all changes of state are of equal interest to
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
object; that is, a change to a single
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
object to be registered with one
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:
- The subject should provide an interface for registering and unregistering for change notifications
- One of the following two must be true:
- 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.
- In the push model: The subject should send the state information that the observers may be interested in.
- Observers should provide an interface for receiving notifications from the subject.