Command Palette

Search for a command to run...

PHASE 2Beginner ~7 min· topic 14 of 22Behavioral

Behavioral 2 — Observer

In one line

One subject notifies many listeners when its state changes — the publish/subscribe idea in-process.

0/22 · 0%

Key ideas

  1. 01

    Solves: notifications fan-out (order placed → email, SMS, analytics, inventory).

  2. 02

    Subject keeps List<Observer> and notifies on change; observers subscribe/unsubscribe freely.

  3. 03

    Decoupling direction: subject doesn't know what observers do with the event.

  4. 04

    Beware: synchronous observers can slow the subject — queue them or use an event bus.

  5. 05

    Real-life example: a YouTube channel. You subscribe once, and every new video notifies you. The channel doesn't know or care what you do with the notification.

  6. 06

    Thread safety: if listeners can subscribe while events are firing, use CopyOnWriteArrayList so the loop never throws ConcurrentModificationException.

  7. 07

    Out-of-process version: the same idea across services is pub/sub with Kafka or SNS (Phase 10).

Java / Spring map

  • →

    Spring @EventListener / ApplicationEventPublisher; PropertyChangeSupport; RxJava/Reactor onNext.

Code & diagrams

Observer.javajava

Order events fan out to three listeners.

public interface OrderListener { void onOrder(Order o); }

public class OrderService {
  // CopyOnWriteArrayList: safe if someone subscribes while we are notifying
  private final List<OrderListener> listeners = new CopyOnWriteArrayList<>();
  public void subscribe(OrderListener l)  { listeners.add(l); }
  public void unsubscribe(OrderListener l){ listeners.remove(l); }

  public void place(Order o) {
    persist(o);
    for (OrderListener l : listeners) {
      try { l.onOrder(o); }                            // fan-out
      catch (RuntimeException e) { log.warn("listener failed", e); } // one bad listener can't break the rest
    }
  }
}

class EmailListener implements OrderListener {
  public void onOrder(Order o) { System.out.println("email: " + o.id()); }
}
class AnalyticsListener implements OrderListener {
  public void onOrder(Order o) { System.out.println("track: " + o.id()); }
}
class InventoryListener implements OrderListener {
  public void onOrder(Order o) { System.out.println("deduct: " + o.sku()); }
}

// Spring equivalent:
// @EventListener public void on(OrderPlacedEvent e) { ... }

Explain without notes

01

What happens to latency on the subject as observers grow — and the fix?

Practice

01

Convert to Spring @EventListener with three @Component listeners.

Trade-offs

  • ↔

    Sync fan-out adds latency to the subject; exceptions in one listener can break the whole flow.

Completion checklist

  • I can implement Observer safely (isolated failures, thread-safe list) and say when to move it to a message queue.

Back to phase