# Observer Pattern The **Observer Pattern** defines a one-to-many dependency between objects so that when one object (the **Subject**) changes state, all of its dependents (the **Observers**) are notified and updated automatically. The Subject doesn't know who the Observers are — only that they implement a known notification interface and have registered themselves. It's one of the 23 original Gang of Four patterns. Observer is the canonical structural answer to "I want to react to changes elsewhere without tightly coupling the source to the reactor." ## Structure ``` notifies Subject ─────────────────> Observer (interface) │ △ register/ │ implements unregister │ ┌───────┴───────┐ │ │ ObserverA ObserverB ``` - **Subject** — holds state, maintains a list of registered Observers, exposes `register` / `unregister` / `notify`. - **Observer** — interface with an `update(...)` (or `onEvent(...)`) method. - **ConcreteObserver** — implements `update`, reacts to notifications. The Subject's only knowledge of its Observers is via the interface. Observers can be added or removed at runtime without modifying the Subject. ## Why it matters - **Decouples producers from consumers**: the Subject stays unaware of consumer identity, count, or behavior. - **Open for extension**: new reactions to a state change ship as new Observer classes; the Subject doesn't change. See [[Open Closed Principle (OCP)]]. - **Powers reactive systems**: GUIs, model/view separation, event buses, change-data-capture pipelines, reactive streams — all are Observer at the core. - **Inverts control**: the Subject doesn't *call* into specific consumers; consumers register and the Subject *broadcasts*. This is [[Inversion of Control (IoC)]] in its purest form. ## Common manifestations | Form | Where you see it | |------|-----------------| | Event listeners | DOM (`addEventListener`), Node.js `EventEmitter`, Java Swing/AWT | | Pub/sub buses | Kafka, NATS, RabbitMQ, Redis Pub/Sub, in-process buses | | Reactive streams | RxJS, Reactor, Akka Streams, Flow | | Property bindings | Angular signals, Vue reactivity, Svelte stores, MobX | | Domain events | DDD aggregates publishing events on state change | | OS-level | Unix signals, file watchers (`inotify`, `fsnotify`) | These all share the Observer shape. The differences are mostly transport, threading model, and whether the channel is typed. ## Push vs Pull - **Push** — the Subject sends the new state (or a delta) as part of the notification. Simpler for Observers; can over-deliver data they don't need. - **Pull** — the Subject signals "something changed"; Observers query the Subject for what they want. Less coupling on payload shape; more round-trips. Modern reactive libraries (RxJS, Reactor) standardize on Push with rich operators (`map`, `filter`, `debounce`) layered on top of the Observer pipe. ## Pitfalls - **Memory leaks**: Observers that don't unregister keep the Subject (and their own state) alive. Classic in long-lived UIs and SPAs. - **Notification storms / cascading updates**: an Observer reacting by changing a Subject that fires another notification can loop, fan out exponentially, or thrash the system. - **Ordering surprises**: most plain Observer implementations don't guarantee notification order; behavior depending on order is fragile. - **Hidden dependency graph**: it becomes hard to reason about *why* something updated — the source isn't on the call stack of the reactor. - **Threading**: notifications may arrive on the publisher's thread, the registration thread, or a dedicated dispatcher thread. Mismatched assumptions cause races. ## Observer vs Strategy vs Template Method - **[[Strategy Pattern]]**: pluggable algorithm. One-to-one relationship; call returns a result. - **[[Template Method]]**: vary steps of a fixed algorithm via subclassing. - **Observer**: one-to-many notification of state change; fire-and-forget. ## References - Gang of Four — *Design Patterns: Elements of Reusable Object-Oriented Software* (1994), Observer chapter - Refactoring Guru — https://refactoring.guru/design-patterns/observer ## Related - [[Strategy Pattern]] - [[Template Method]] - [[Inversion of Control (IoC)]] - [[Loose Coupling]] - [[Open Closed Principle (OCP)]] - [[SOLID Principles]]