Observer Pattern Implementor
by @quochungto
Implement the Observer pattern to establish one-to-many dependencies where changing one object automatically notifies and updates all dependents. Use when a...
Example 1: Spreadsheet Model with Multiple Chart Views
Scenario: A spreadsheet has a data model that three chart widgets (bar chart, pie chart, line chart) read directly. Currently the model calls barChart.refresh(), pieChart.refresh(), and lineChart.refresh() in its SetCell method. Adding a fourth chart requires modifying the model.
Trigger: "Every new chart type requires touching the spreadsheet model."
Process:
SpreadsheetModel directly references three concrete chart classesSpreadsheetModel becomes ConcreteSubject; each chart implements ObserverList in Subject (few subjects, multiple observers)SetCell calls Notify() after updating dataNotify is last in SetCell β state is fully updated firstGetCellValue(row, col) in their UpdateOutput: SpreadsheetModel has no reference to any chart class. New charts attach themselves; model never changes.
Example 2: Clock with Multiple Display Observers
Scenario: A ClockTimer (concrete subject) notifies time displays. A DigitalClock and AnalogClock both observe the same timer. This is the canonical sample from the GoF text.
Trigger: "Both clock displays must always show the same time, but neither should know about the other."
Key implementation details:
DigitalClock inherits from both Widget (UI toolkit) and Observer (combining concern 10 β Subject/Observer in one class hierarchy via multiple inheritance)_subject->Attach(this); destructor calls _subject->Detach(this) β full lifecycle managementUpdate guards on subject identity: if (theChangedSubject == _subject) β handles potential future case of observing multiple subjectsvoid DigitalClock::Update(Subject* theChangedSubject) {
if (theChangedSubject == _subject) {
Draw();
}
}void DigitalClock::Draw() {
int hour = _subject->GetHour();
int minute = _subject->GetMinute();
// render digital display
}
Output: ClockTimer::Tick() calls Notify(); both displays update independently without knowing each other exist.
Example 3: Multi-Subject Dashboard with ChangeManager
Scenario: A financial dashboard has three data subjects: PriceSubject, VolumeSubject, and PositionSubject. A RiskSummaryObserver observes all three. When a trade executes, all three subjects change in one operation. Without ChangeManager, RiskSummaryObserver.Update fires three times for one logical event.
Trigger: "Our risk view recalculates three times per trade because it observes three subjects."
Process:
DAGChangeManager. Each subject calls ChangeManager::Instance()->Notify(). DAGChangeManager marks RiskSummaryObserver when PriceSubject changes, marks it again when VolumeSubject changes (already marked β no-op), then updates it once.Output: One trade β three subject changes β RiskSummaryObserver.Update called exactly once.
clawhub install bookforge-observer-pattern-implementor