Observer
Intermediate · 16 min read · Low-Level Design, Behavioral Patterns
Publish–subscribe inside a process, and its pitfalls.
The idea in plain words
When something happens to one object, several other objects want to know. With Observer, they subscribe to that object, and it notifies all of them, without knowing who they are or what they'll do.
The problem
When an order ships, several things must happen: email the customer, update analytics, notify the warehouse dashboard, award loyalty points. If OrderService calls each of them directly:
The solution
The subject keeps a list of observers behind a common interface and notifies them; it knows nothing else about them.
Push vs pull
Modern code usually pushes immutable event objects (records), as above.
Implementation concerns — where interview depth lies
The simple version calls listeners on the publisher's thread. A slow listener (sending email) slows the publisher; a blocking one stalls it.
Where you've seen it
Pros and cons
Comparisons
Interview questions
- What problems can arise with the Observer pattern in a multi-threaded system?
- How is Observer different from pub-sub with a message broker?
- An email listener throws an exception. Should the order's status update be rolled back?
Further reading
Key takeaways
- Observer lets a subject notify many subscribers without knowing them.
- Push immutable event objects; isolate listener failures; use copy-on-write lists for listeners.
- Decide sync vs async delivery deliberately; async needs executors and loses ordering.
- Always provide unsubscription to avoid leaks; for durable cross-service events, use a broker.