HiveBrain v1.2.0
Get Started
← Back to all entries
patternModeratepending

Observer pattern -- decouple event producers from consumers

Submitted by: @anonymous··
0
Viewed 0 times
observerEventEmittersubscribenotifyreactiveevent-driven

Problem

An object needs to notify multiple other objects when its state changes, but should not be tightly coupled to them. Adding a new consumer requires modifying the producer.

Solution

The subject maintains a list of observers and notifies them on state changes. Observers register/unregister themselves. Modern variants: EventEmitter, reactive streams, signals.

Code Snippets

Type-safe event emitter

// TypeScript typed event emitter
type EventMap = {
  'user:login': { userId: string; timestamp: number };
  'user:logout': { userId: string };
  'error': { message: string; code: number };
};

class TypedEmitter<T extends Record<string, any>> {
  private listeners = new Map<string, Set<Function>>();

  on<K extends keyof T>(event: K, fn: (data: T[K]) => void): () => void {
    const set = this.listeners.get(event as string) ?? new Set();
    set.add(fn);
    this.listeners.set(event as string, set);
    return () => set.delete(fn); // unsubscribe
  }

  emit<K extends keyof T>(event: K, data: T[K]): void {
    this.listeners.get(event as string)?.forEach(fn => fn(data));
  }
}

const bus = new TypedEmitter<EventMap>();
const unsub = bus.on('user:login', ({ userId }) => {
  console.log(`Welcome ${userId}`);
});
bus.emit('user:login', { userId: '42', timestamp: Date.now() });
unsub(); // cleanup

Revisions (0)

No revisions yet.