Up Java Resources

Observer/Observable Pattern

Basic Ideas:
  1. The Observer pattern is used to keep consistency between related objects while minimizing their coupling and maximizing reusability (or independence) of the objects.
  2. Creates a one-to-many relationship between a subject and its observers. All observers are notified when there is a change to the subject. The observers then query the subject to synchronize themselves.
When to use this pattern:
  1. When a change to one object requires the change of a variable number of other objects (not necessarily known at compile-time).
  2. When an object should be able to talk to another object, but you don't want them essentially dependent on each other.
Benefits:
  1. Can add new subjects and new observers all independently of all other subjects and observers.
  2. Minimal dependence between subject and observer
  3. Subject doesn't need to know how many observers it has. It simply broadcasts a change in state.
Pitfalls:
  1. Because observers don't know about each other, a simple update to an observer might cause a long chain of other updates.
  2. Each observer decides whether it needs to update something when it receives the notification from the subject that something has changed. Therefore, complicated observers have to do a lot of work to figure out what changed when they receive a notification.
Implementation Issues:
  1. How to keep track of the subject to observer mapping?
    • Hash table: simple and best use of storage.
  2. How to observe more than one subject?
    • Pass reference of the subject when making notification so the observer knows which subject to check.
  3. Who calls Notify?
    • Subject: every time the subject sees a change it calls notify. However, this may lead to many unnecessary calls if multiple things are changing at a time.
    • Observer: when observer is finished with updates, can call notify. This will minimize the number of notify calls made, but forces the observer to remember to call notify after every change is made.
  4. When a subject is deleted, what happens to its observers?
    • Subject should notify its observers, so they can delete reference to it.
  5. Make sure subject is self-consistent before calling notify.
    • Make "notify" the last statement in an abstract class's template method
  6. How much information to give an observer when notifying of change?
    • Push model: give the observer detailed information about the change good because makes work easy for the observer. Bad because makes the code less reusable and assumes knowledge about the structure and needs of the subject's observers.
    • Pull model: gives minimal change information. Makes life hard for the observers; they must figure out what changed with no help from the subject.
    • Find a happy median.
  7. Limit update calls that don't affect a particular observer?
    • When an observer registers with a subject, also tells the subject of which types of events it wants to be notified. Can create an Aspect class whose objects are passed on registration with a subject.
Handling complex relationships in updates with Change Managers:
  1. Can use a Change Manager to interface with particularly complex updates.
    • Keeps track of the subject/observer mapping, eliminating need for subjects and observers to keep references of each other.
    • Defines update strategy
    • Updates observers when subject notifies Manager of a change.
    • Simple Managers may just update every registered observer upon notification from a subject.
    • If observers are dependent upon multiple subjects, observers may receive redundant update notifications. A more complex Manager can keep track of this information and ensure that only one update is received per Observer.
  2. Note: Change Manager is an instance of the Mediator pattern.

Pros and cons of different update semantics

Semantic \ Qualities Design abstraction (i.e. decoupling) Efficiency Simplicity
Push bad good good
Pull good bad good
Change Manager good good bad