What It Is
The Observer pattern lets one object announce events to many subscribers without knowing who they are. Subscribers register once; from then on, every event reaches all of them automatically.
The publisher depends only on a small subscriber protocol — new kinds of listeners appear without one line changing in the publisher.
Example: One Alert, Every Subscriber
The monitor keeps a list of subscribers. When something happens, it notifies the whole list — an email alert and a dashboard, today; a chat message tomorrow, by just subscribing it.
Publish once, deliver to all
One alert() call, two deliveries. The monitor has no idea what an email or a dashboard is — it only knows things that can be notified.
Output: complete Python program
from dataclasses import dataclass
from typing import Protocol
class Subscriber(Protocol):
def notify(self, event: str) -> None: ...
@dataclass
class EmailAlert:
addr: str
def notify(self, event: str) -> None:
print("email to", self.addr + ":", event)
class Dashboard:
def notify(self, event: str) -> None:
print("dashboard shows:", event)
# The publisher keeps a list and notifies everyone on it.
class Monitor:
def __init__(self) -> None:
self.subscribers: list[Subscriber] = []
def subscribe(self, subscriber: Subscriber) -> None:
self.subscribers.append(subscriber)
def alert(self, event: str) -> None:
for subscriber in self.subscribers:
subscriber.notify(event)
m = Monitor()
m.subscribe(EmailAlert(addr="ops@example.com"))
m.subscribe(Dashboard())
m.alert("disk almost full")
When to Use It
Use it when several parts must react to the same events and the list of reactors changes — UI updates, alerting, cache invalidation, activity feeds.
Skip it when exactly one, fixed receiver exists — call it directly. And for very simple cases, a plain list of callback functions gives the pattern's shape with no class machinery at all.
Pros and Cons
Pros: publisher and subscribers stay decoupled; subscribers come and go at run time; new reactions need no publisher changes.
Cons: the flow becomes invisible — "who reacts to this?" takes searching; a slow or failing subscriber can stall the notify loop; forgotten unsubscribes leak.