Also known as Publish-Subscribe, Dependents.
As stated in GoF, p293 :
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
"How to define a subscription mechanism to notify objects about an event ?"
Yup, just like Emails subscription, RSS feeds, GUI libraries and so on !
You should use the Observer pattern in the following cases :
- When you need changes on an object to affect other objects.
- When you want to manage the subscribers dynamically ( or you do not know them beforehand )
- When you objects that must observe others but only under particular circumstances (time, conditions...).
Participants
- Subject
- Provides an interface to add/remove Observers.
- Maintains an list (an array of references for example) of its Observers.
- Observer : Defines an updating interface for objects that should be notified of changes in a subject.
- ConcreteSubject
- Stores the state of interest to ConcreteObserver objects.
- Implements the notify() method to notify its Observers when a change occurs.
- ConcreteObserver
- Maintains a reference to a ConcreteSubject object.
- Implements the Observer updating() interface to keep its state consistent with the ConcreteSubject's.
How to implement
- Break your business logic into two parts :
- The core functionality (independent from other code) that will be the Subject.
- The rest will be the Observers.
- Declare the Observer interface with at least an update() method.
- Declare the Subject interface with methods to add/remove Observers.
- Optionally, you can declare an interface derived from the Subject interface that will implement the subscription list mechanism.
- Create your ConcreteSubject classes.
- Create the ConcreteObserver classes and implement their update() method.
Note : UML class diagram taken from here
Pros
- Open/Closed principle : It is easy to add new ConcreteObservers without breaking any existing code (not even the Subject's code).
- Support broadcast communications (allthough the Observers are notified in a random order).
Cons
- Unexpected updates : A small operation on a ConcreteSubject can cause a lot of updates to the associated Observers.
Here are some usefull ressources :
- w3sdesign
- A Refactoring guru article.
- A complete example here