Overview
The Observer pattern lets an object (the subject) notify a list of dependents (observers) automatically when its state changes. The subject only knows that observers implement an update interface; it does not know what they do.
It is the foundation of event listeners in the browser, reactive UI frameworks, pub/sub systems, and domain events. It decouples the thing that changes from the things that react.
When a channel uploads a video, every subscriber is notified. The channel does not know or care whether you watch on a phone or a TV. You can subscribe or unsubscribe at any time.
When to use it
- A change in one object must trigger actions in others, and the set of reactions changes over time.
- You want to add reactions such as email, analytics, or cache invalidation without editing the core logic.
- Several UI components must stay in sync with one model.
Where it shows up in interviews
Recognize it when: one change must notify many dependents.
- Design a stock price alert system
- Design a notification service
- Design a parking lot display board
Recognize it when: adding reactions should not change the source.
- Design an order pipeline
- Design a weather station
Where it is used in real software
addEventListener lets many handlers observe clicks and input.
Observables push values to subscribers.
Beans publish events that listeners handle without direct coupling.
Key terms
- Subject
- The object being watched; keeps a list of observers.
- Observer
- An object that implements update(event).
- Subscribe / unsubscribe
- Adding or removing an observer from the list.
- Push vs pull
- Push sends data with the notification; pull lets observers query the subject.
How it works
- 1Define the observer interface
For example, OrderObserver.onOrderPlaced(order).
- 2Keep a list in the subject
The subject exposes subscribe and unsubscribe methods.
- 3Change state and notify
After a state change, the subject loops through observers and calls their method.
- 4Observers react independently
Email, inventory, and analytics each handle the event their own way.
Order placed event
OrderService places an order; three observers react
| Observer | Reaction | Can be added without editing OrderService? |
|---|---|---|
| EmailObserver | Send confirmation email | Yes |
| InventoryObserver | Reserve stock | Yes |
| AnalyticsObserver | Record a conversion | Yes |
NOWObserver: EmailObserver | Reaction: Send confirmation email | Can be added without editing OrderService?: Yes
OrderService only calls notify. A new LoyaltyPointsObserver can be registered with one line and no changes to order logic.
Implementation
interface OrderObserver { onOrderPlaced(order: Order): void;} class OrderService { private observers = new Set<OrderObserver>(); subscribe(observer: OrderObserver): () => void { this.observers.add(observer); return () => this.observers.delete(observer); // unsubscribe handle } placeOrder(order: Order): void { // ... validate and persist ... for (const observer of this.observers) { try { observer.onOrderPlaced(order); } catch (error) { console.error("Observer failed", error); // one failure must not stop others } } }} class EmailObserver implements OrderObserver { onOrderPlaced(order: Order) { mailer.send(order.customerEmail, `Order ${order.id} confirmed`); }} const service = new OrderService();service.subscribe(new EmailObserver());service.subscribe({ onOrderPlaced: (order) => analytics.track("purchase", order.total) });Complexity and performance
Each observer is called once per event.
With a set or list.
Trade-offs
It is harder to see what happens after a change because reactions are registered elsewhere. Document events and keep observers small.
A slow observer slows the subject. For slow work, publish to a queue and process asynchronously.
Observers should not depend on each other's execution order.
Variants and related techniques
Observers subscribe by event name: on('placed', handler).
A broker sits between publishers and subscribers, so they do not reference each other at all.
RxJS and similar libraries treat events as streams with operators like map and filter.
Common mistakes
- Memory leaks from never unsubscribing.
Fix: Return an unsubscribe function and call it when the observer is disposed.
- One observer's exception stops the rest.
Fix: Catch errors per observer, or dispatch asynchronously.
- Observers modifying the subject during notification.
Fix: Iterate over a copy of the list and avoid re-entrant updates.
Interview questions
Observer vs Pub/Sub?
In Observer, the subject holds direct references to observers. In pub/sub, a broker decouples them completely, which supports different processes and machines.
How would you make observers asynchronous?
Push events into a queue or event bus and have observers consume them independently, with retries for failures.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Stock price ticker | Easy | Multiple displays subscribe to one feed. |
| Notification service | Medium | Email, SMS, push observers with user preferences. |