Photo by Daniel Lerman / Unsplash

TIL - Observer Pattern Decouples Event Producers From Consumers

Today I Learned May 16, 2026

The subject broadcasts state changes without knowing who listens. Observers register themselves and react independently - no tight coupling between the event source and its handlers.

from typing import Callable

class EventEmitter:
    def __init__(self):
        self._listeners: dict[str, list[Callable]] = {}

    def on(self, event: str, callback: Callable):
        self._listeners.setdefault(event, []).append(callback)

    def emit(self, event: str, *args, **kwargs):
        for cb in self._listeners.get(event, []):
            cb(*args, **kwargs)

emitter = EventEmitter()

emitter.on("user.created", lambda u: print(f"Send welcome email to {u}"))
emitter.on("user.created", lambda u: print(f"Log signup for {u}"))

emitter.emit("user.created", "[email protected]")
# Send welcome email to [email protected]
# Log signup for [email protected]

Each listener is independently addable and removable - new side effects never require modifying the emitting code.

Tags