To design a consistent communication model between a set of dependent objects and an object that they are dependent on.
- Dependent object: Observers
- The object they dependent on: Subject
- The relationship is 1 Subject – n Observers. The state of Observers are synchronized with the state of Subject
- Mechanism: publisher – subscriber.
When to use:
The Observers are interesting in or dependent on the states of a Subject. Each Observer need to know when the subject’s state changed.
- The Observers list are changed dynamically, so Subject CANNOT maintain a statistic list of Observers.
- The Observers’s state need to synchronize with the subject’s state
- Lets think about publisher-subcriber. When a publisher publishes a new, all of the subcribers should be notified.
Example use cases:
- ReportManager (sub), MonthlyReport(obs), YTDChart(obs): when user choose a department from ReportMangaer, the Monthly Report and YTDCharts need to be calculate and report for that particular DEPARTMENT.
- Quora question topic, followers are observers as they will receive notification when a new answer is coming.
To implement publisher – subcriber mechanism, the subject must provide an interface (Observable) for register/unregister, and notify the observers. The Observer also need to implement an interface for receiving the notification.
Take the ReportManager as an Example, ReportManager is a Subject and implement ObservableInterface (register/unregister, notif), and it has own method to make its string ‘depart’ change. Once changed, loop through observers list and call each observer’s interface method refreshData() with ‘this’, to update the data.
On the other hand, Each observer’s refeshData() will check the passing argument, (which is a Subject Interface) against its registering Subject to prevent unintended call. Then update itself based on the passing argument.
- Observers can change its subject state during refesh() process, which ll make the flow inconsistent. What the solution?
– Pass only read-only Subject interface to the observer, not the ConcreteSubject itself. Cause there s no Mutator methods, the observer cannot change.
– Other method: check Stackflow answer here