Ce este
Șablonul Observator (Observer) permite unui obiect să anunțe evenimente către mulți abonați fără să știe cine sunt aceștia. Abonații se înregistrează o singură dată; de atunci încolo, fiecare eveniment ajunge automat la toți.
Publicatorul depinde doar de un mic protocol al abonaților — apar noi tipuri de ascultători fără să se schimbe nicio linie în publicator.
Exemplu: o alertă, toți abonații
Monitorul păstrează o listă de abonați. Când se întâmplă ceva, anunță întreaga listă — azi o alertă prin e-mail și un panou de control; mâine un mesaj de chat, doar prin abonarea lui.
Publici o dată, livrezi tuturor
Un singur apel alert(), două livrări. Monitorul habar nu are ce este un e-mail sau un panou de control — știe doar despre lucruri care pot fi anunțate.
Ieșire: program Python complet
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("e-mail către", self.addr + ":", event)
class Dashboard:
def notify(self, event: str) -> None:
print("panoul de control afișează:", event)
# Publicatorul păstrează o listă și îi anunță pe toți cei din ea.
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")
Când să-l folosești
Folosește-l când mai multe părți trebuie să reacționeze la aceleași evenimente și lista celor care reacționează se schimbă — actualizări ale interfeței, alerte, invalidarea cache-ului, fluxuri de activitate.
Renunță la el când există exact un singur destinatar, fix — apelează-l direct. Iar pentru cazuri foarte simple, o simplă listă de funcții callback oferă forma șablonului fără niciun mecanism de clase.
Avantaje și dezavantaje
Avantaje: publicatorul și abonații rămân decuplați; abonații vin și pleacă în timpul rulării; reacțiile noi nu necesită modificări în publicator.
Dezavantaje: fluxul devine invizibil — „cine reacționează la asta?” necesită căutare; un abonat lent sau care eșuează poate bloca bucla de notificare; dezabonările uitate produc scurgeri de memorie.