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.

Previous: Strategy · Next: State