Skip to content
All essays
ArchitectureMarch 27, 20258 min

Observer Pattern: Build Reactive Systems

Master the Observer pattern. Build reactive systems with event-driven architecture and loose coupling.

Ü
Ümit Uz
Mobile & Full Stack Developer

Understanding the Observer Pattern

The Observer pattern defines a one-to-many dependency between objects. When one object changes state, all dependents are notified automatically.

typescript
// Subject
class NewsAgency {
  private subscribers: Observer[] = [];
  
  subscribe(observer: Observer) {
    this.subscribers.push(observer);
  }
  
  notify(news: string) {
    this.subscribers.forEach(s => s.update(news));
  }
}

// Observer
interface Observer {
  update(news: string): void;
}

class NewsChannel implements Observer {
  update(news: string) {
    console.log('Breaking:', news);
  }
}

Use Cases

Event Handling

typescript
class EventEmitter {
  private listeners: Map<string, Function[]> = new Map();
  
  on(event: string, callback: Function) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, []);
    }
    this.listeners.get(event)!.push(callback);
  }
  
  emit(event: string, data: any) {
    this.listeners.get(event)?.forEach(cb => cb(data));
  }
}

Reactive Programming

typescript
class Observable<T> {
  private observers: ((value: T) => void)[] = [];
  
  subscribe(observer: (value: T) => void) {
    this.observers.push(observer);
  }
  
  next(value: T) {
    this.observers.forEach(o => o(value));
  }
}

const counter = new Observable<number>();

counter.subscribe(value => console.log('Value:', value));

counter.next(1);  // Value: 1
counter.next(2);  // Value: 2

Implementation Patterns

Push Model

typescript
// Subject pushes updates
interface Observer {
  update(data: any): void;
}

class Subject {
  private observers: Observer[] = [];
  
  notify(data: any) {
    this.observers.forEach(o => o.update(data));
  }
}

Pull Model

typescript
// Observer pulls data
interface Observer {
  update(): void;
  getData(): any;
}

class Subject {
  private observers: Observer[] = [];
  
  notify() {
    this.observers.forEach(o => o.update());
  }
}

Benefits

  1. 1Loose coupling between subjects and observers
  2. 2Dynamic relationship at runtime
  3. 3Broadcast communication
  4. 4Open/closed principle

Conclusion

The Observer pattern enables reactive, event-driven systems. Use it for UI updates, event handling, and pub/sub systems.

Build reactive systems with the Observer pattern!

Enjoyed this essay? Share it.

Related essays

Next essay
CLI Frameworks: Build Professional Command-Line Tools