Observer Pattern
The Observer pattern defines one-to-many dependency: when subject state changes, observers update automatically.
Introduction
The Observer pattern defines one-to-many dependency: when subject state changes, observers update automatically. Movie seat availability, stock prices, and order status notifications fit naturally.
Java's deprecated Observable/Observer is avoid — implement custom interfaces or use event bus in production. In interviews, clear Subject/Observer interfaces show you understand decoupled notification.
Watch for memory leaks if observers are not unregistered.
Understanding the topic
Key concepts
- Subject maintains observer list and notifies on change.
- Observer interface with update/onEvent method.
- Push model sends data; pull model lets observer query.
- Decouples event source from UI, email, SMS handlers.
- Domain events variant in DDD-style designs.
- Thread safety if notifications cross threads.
flowchart LRSubject -->|notify| ObserverASubject -->|notify| ObserverB
Step-by-step explanation
- Subject exposes subscribe/unsubscribe.
- Observers register interest.
- State change calls notifyObservers().
- Each observer handles event idempotently.
- Unsubscribe when observer lifecycle ends.
- Optional event object carries payload.
Informative example
Seat availability subject notifying booking UI observers:
public interface SeatObserver {void onSeatsChanged(String showId, Set<String> available);}public final class SeatInventory implements SeatObserver {private final Set<SeatObserver> observers = new CopyOnWriteArraySet<>();private final Map<String, Set<String>> availableByShow = new ConcurrentHashMap<>();public void subscribe(SeatObserver observer) { observers.add(observer); }public void release(String showId, String seatId) {availableByShow.computeIfAbsent(showId, k -> ConcurrentHashMap.newKeySet()).add(seatId);notify(showId);}private void notify(String showId) {Set<String> seats = Set.copyOf(availableByShow.getOrDefault(showId, Set.of()));observers.forEach(o -> o.onSeatsChanged(showId, seats));}@Overridepublic void onSeatsChanged(String showId, Set<String> available) { /* no-op for self */ }}
CopyOnWriteArraySet safe for iterate-notify; production may use event bus — pattern intent matters in interviews.
Real-world use
Real-world applications
- UI updates on model changes.
- Order status notifications.
- Metrics listeners on cache eviction.
Best practices
- Keep observer callbacks fast — offload heavy work.
- Use weak references or explicit unsubscribe.
- Immutable event payloads prevent races.
- Consider ordered delivery requirements.
- Idempotent handlers for duplicate events.
Common mistakes
- Observer doing transactional side effects synchronously.
- Circular notify loops between subjects.
- Forgotten unsubscribe leaking memory.
- Fat observer interface forcing empty methods (ISP violation).
Advanced interview questions
Interview Prep
Practice concise answers, then expand each card for the explanation.
1BeginnerQuestionWhat is Observer pattern?+
Answer
2BeginnerQuestionObserver vs pub/sub?+
Answer
3IntermediateQuestionHow prevent memory leaks?+
Answer
4IntermediateQuestionThread-safe observer list?+
Answer
5AdvancedQuestionDesign notify for splitwise expense added.+
Answer
Summary
Observer decouples state change from reactions. Subject maintains subscriber list. Unregister observers to avoid leaks. Keep notification handlers lightweight. Foundation for event-driven LLD modules.