Sunday, July 11, 2010

Observer Pattern

What

Let's say we have an object O whose state may change at anytime. There are other objects in our system that are interested in knowing when the state of object O changes. What we need is a way for object O to notify all the interested objects when its state changes. The Observer Pattern facilitates exactly that. It defines a one-to-many relationship between objects such that when one object changes its state, all dependent objects are notified. There are two kinds of the participants in the Observer Pattern:

  1. The Subject also known as the Observable or the Publisher
  2. The Observers also known as the Subscribers
The Observers register themselves with the Subject. The Subject notifies the registered Observers when a change in its state occurs. The order of notification to the registered Observers by the Subject is non-deterministic. That is, an Observer does not know whether it received the update notification from the Subject before or after other Observers.

 

Why

The biggest benefit of the Observer Pattern is the loose coupling between the Subject and the Observers. As long as the Observers implement an update notification interface supported by the Subject, they may register themselves for the update notifications. Conversely, the Observers know the Subject through Subject's well-defined interfaces. An Observer may unregister with the Subject if it is no longer interested in the notifications.

 

How

interface IObservableSubject
{
  void RegisterObserver(IObserver observer);
  void UnRegisterObserver(IObserver observer);
  void NotifyObservers();
}
interface IObserver
{
  void Update(IObservableSubject observableSubject);
}

A concrete ObservableSubject class implements the IObservableSubject interface along with its other core functionality. Internally, ObservableSubject object keeps a list of registered Observers and notifies them by calling their Update() method. Once notified of the update, the Observer objects may call query methods on the ObservableSubject object to retrieve the state they are interested in.

A concrete Observer class implements the IObserver interface along with its other core functionality. The Observer class gets a reference to the concrete ObservableSubject class through its constructor. Typically in its constructor, the Observer object adds itself to the list of observers maintained by the ObservableSubject object by invoking the IObservableSubject::RegisterObserver() method.

The implementation of Observer Pattern through interfaces is preferred over inheritance because an interface allows us to turn existing classes into Observers by simply implementing the IObserver interface. The same argument holds true when turning an existing class into an ObservableSubject by implementing the IObservableSubject interface.