Low-Level Design Tutorial 0/42 lessons ~6 min read Lesson 25

    Observer Pattern

    The Observer pattern defines one-to-many dependency: when subject state changes, observers update automatically.

    Course progress0%
    Focus
    9 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    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.
    text
    flowchart LR
    Subject -->|notify| ObserverA
    Subject -->|notify| ObserverB

    Step-by-step explanation

    1. Subject exposes subscribe/unsubscribe.
    2. Observers register interest.
    3. State change calls notifyObservers().
    4. Each observer handles event idempotently.
    5. Unsubscribe when observer lifecycle ends.
    6. Optional event object carries payload.

    Informative example

    Seat availability subject notifying booking UI observers:

    java
    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));
    }
    @Override
    public 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

    Q1BeginnerWhat is Observer pattern?
    Subject notifies registered observers automatically when state changes.
    Q2BeginnerObserver vs pub/sub?
    Observer often in-process direct list; pub/sub usually brokered async messaging.
    Q3IntermediateHow prevent memory leaks?
    Unsubscribe on destroy; weak references; lifecycle-aware registration.
    Q4IntermediateThread-safe observer list?
    CopyOnWriteArrayList or synchronized block during notify.
    Q5AdvancedDesign notify for splitwise expense added.
    GroupLedger subject; MemberBalanceObserver updates UI; Event carries expense id and splits.

    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.

    Ready to mark this lesson complete?Track your journey across the entire course.