Паттерн Observer (Наблюдатель) — это поведенческий паттерн, который позволяет объектам подписываться на события и получать уведомления при их наступлении. Это создает механизм подписки/публикации для рассылки событий множеству объектов.
Паттерн состоит из двух основных компонентов:
from abc import ABC, abstractmethod
class Observer(ABC):
"""Абстрактный наблюдатель"""
@abstractmethod
def update(self, subject):
"""Получение обновления от субъекта"""
pass
class Subject(ABC):
"""Абстрактный субъект"""
def __init__(self):
self._observers = []
def attach(self, observer):
"""Подписать наблюдателя"""
if observer not in self._observers:
self._observers.append(observer)
def detach(self, observer):
"""Отписать наблюдателя"""
self._observers.remove(observer)
def notify(self):
"""Уведомить всех наблюдателей"""
for observer in self._observers:
observer.update(self)
class ConcreteSubject(Subject):
"""Конкретный субъект с состоянием"""
def __init__(self):
super().__init__()
self._state = None
@property
def state(self):
return self._state
@state.setter
def state(self, value):
self._state = value
self.notify() # Автоматическое уведомление при изменении
class ConcreteObserverA(Observer):
"""Конкретный наблюдатель типа A"""
def update(self, subject):
print(f"ObserverA: Reacted to state change: {subject.state}")
class ConcreteObserverB(Observer):
"""Конкретный наблюдатель типа B"""
def update(self, subject):
print(f"ObserverB: Reacted to state change: {subject.state}")
if __name__ == "__main__":
subject = ConcreteSubject()
observer_a = ConcreteObserverA()
subject.attach(observer_a)
observer_b = ConcreteObserverB()
subject.attach(observer_b)
subject.state = "First state" # Оба наблюдателя получат уведомление
subject.state = "Second state" # Оба наблюдателя получат уведомление
subject.detach(observer_a)
subject.state = "Third state" # Только observer_b получит уведомление
class Event:
"""Класс события"""
def __init__(self):
self.handlers = []
def subscribe(self, handler):
self.handlers.append(handler)
def unsubscribe(self, handler):
self.handlers.remove(handler)
def fire(self, *args, **kwargs):
for handler in self.handlers:
handler(*args, **kwargs)
class Publisher:
"""Издатель событий"""
def __init__(self):
self.on_change = Event()
def do_something(self):
self.on_change.fire("Something happened!")
import weakref
class WeakRefObserver:
def __init__(self):
self._observers = weakref.WeakSet()
def attach(self, observer):
self._observers.add(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
Плюсы:
Минусы:
asyncio
, который предоставляет похожий функционал через очередиПаттерн Observer — мощный инструмент для создания гибких систем с низкой связанностью компонентов.