Observer Pattern Explained

Build event-driven systems with loose coupling

The Problem

Imagine you have a shopping cart. When items change:

  • UI needs to update
  • Analytics needs to track
  • Inventory needs to adjust
  • Email service needs to notify

Without Observer: Each component directly calls the others. Tight coupling nightmare.

The Solution: Observer Pattern

One-to-many dependency where changes in one object automatically notify all dependents.

// When the subject changes...
subject.notify()

// ...all observers get updated automatically
// No tight coupling required!

How It Works

Key Players:

  1. Subject - Maintains list of observers, notifies them of changes
  2. Observer - Defines update interface for receiving notifications
  3. ConcreteSubject - Stores state, sends notifications on change
  4. ConcreteObserver - Implements update logic

Flow: Subject state changes → notify() called → All observers updated

Code Example: Subject

interface Observer {
  update(data: any): void
}

class Subject {
  private observers = new Set<Observer>()

  attach(observer: Observer): void {
    this.observers.add(observer)
  }

  detach(observer: Observer): void {
    this.observers.delete(observer)
  }

  notify(data: any): void {
    this.observers.forEach(obs => obs.update(data))
  }
}

Code Example: Observers

class ShoppingCart extends Subject {
  private items: string[] = []

  addItem(item: string) {
    this.items.push(item)
    this.notify({ items: this.items, action: 'add' })
  }
}

class EmailObserver implements Observer {
  update(data: any) {
    console.log(`Sending email: Item ${data.action}ed`)
  }
}

class AnalyticsObserver implements Observer {
  update(data: any) {
    console.log(`Tracking: ${data.items.length} items`)
  }
}

Real-World Use Cases

1. Event Systems

button.addEventListener('click', handler)

2. MVC Architecture

Model notifies View of data changes

3. Reactive Programming

RxJS Observables, React state management

4. Stock Market Apps

Price changes notify all dashboard widgets

Observer vs Pub/Sub

Observer Pattern

  • Direct coupling - Subject knows its observers
  • Synchronous - Immediate notification
  • Single application scope
  • Example: DOM events

Pub/Sub Pattern

  • Decoupled - Publisher doesn't know subscribers
  • Asynchronous - Via message broker
  • Cross-application scope
  • Example: Apache Kafka, Redis

When to Use (and When NOT to)

Use Observer When:

  • State changes need to update multiple components
  • You want loose coupling between objects
  • Number of observers is dynamic (add/remove at runtime)
  • Building event-driven systems

DON'T Use When:

  • Simple, direct method call would suffice
  • Only one or two static dependencies
  • Performance is critical (notification overhead)
  • You need guaranteed delivery or ordering

Key Takeaways

  1. Decouples objects - Subject doesn't know specifics about observers
  2. Scalable - Easy to add/remove observers at runtime
  3. Watch for leaks - Always unsubscribe when done
  4. Push vs Pull - Push sends data, Pull lets observers query

Remember: The Observer pattern is everywhere in modern development - from DOM events to reactive state management.

Start using it when you find yourself writing notification code!

1 / 0
Observer Pattern Explained