Ответ
Наблюдатель (Observer) — это поведенческий паттерн проектирования, который создает механизм подписки, позволяющий одним объектам следить за изменениями в других объектах и реагировать на них.
Основные участники:
- Издатель (Subject/Observable): Объект, который содержит важное состояние и уведомляет подписчиков о его изменениях.
- Подписчик (Observer/Listener): Объект, который хочет получать уведомления об изменениях в издателе.
Ключевая идея: Издатель не знает ничего о конкретных классах подписчиков, только о том, что они реализуют общий интерфейс. Это обеспечивает слабую связанность между компонентами системы.
Пример на Python:
Создадим простой менеджер событий (EventManager), который уведомляет подписчиков (LoggerListener, EmailListener) о различных событиях.
from abc import ABC, abstractmethod
from typing import List
# Интерфейс подписчика
class IListener(ABC):
@abstractmethod
def update(self, event_type: str, data: any):
pass
# Издатель
class EventManager:
def __init__(self):
self._listeners: List[IListener] = []
def subscribe(self, listener: IListener):
self._listeners.append(listener)
def unsubscribe(self, listener: IListener):
self._listeners.remove(listener)
def notify(self, event_type: str, data: any):
print(f"nEventManager: Notifying about '{event_type}' event...")
for listener in self._listeners:
listener.update(event_type, data)
# Конкретные подписчики
class LoggerListener(IListener):
def update(self, event_type: str, data: any):
print(f"Logger: Event '{event_type}' with data '{data}' was logged.")
class EmailListener(IListener):
def update(self, event_type: str, data: any):
print(f"EmailSender: Sending email about '{event_type}' event.")
# Клиентский код
manager = EventManager()
logger = LoggerListener()
email_sender = EmailListener()
manager.subscribe(logger)
manager.subscribe(email_sender)
manager.notify("user_login", {"user_id": 123})
manager.unsubscribe(email_sender)
manager.notify("order_placed", {"order_id": 456})
Когда использовать:
- Когда изменения в состоянии одного объекта требуют изменения в других, но вы не хотите, чтобы эти объекты были жестко связаны.
- В системах обработки событий (GUI, веб-фреймворки).
- Для реализации реактивного программирования.
Преимущества:
- Слабая связанность: Издатель и подписчики независимы друг от друга.
- Гибкость: Можно добавлять и удалять подписчиков на лету.
Ответ 18+ 🔞
А, слушай, вот эта штука — Наблюдатель! Ну, паттерн такой, поведенческий. Представь себе, блядь, как в жизни: есть один чувак, который орет на всю улицу, что у него скидка на пиво, а вокруг него куча алкашей, которые эту новость ловят и сразу бегут в магаз. Вот это оно и есть, ёпта!
Кто тут главный по тарелкам:
- Издатель (Subject): Это тот самый орущий чувак. У него есть какое-то важное состояние — ну, там, цена на пиво упала. И он, сука, обязан проорать об этом всем, кто на него подписался.
- Подписчик (Observer): Это алкаш, который уши навострил. Его задача — услышать крик и отреагировать: ноги в руки и бежать за дешёвым бухлом.
Соль в чём, блядь: Издатель вообще не в курсе, кто конкретно его слушает — Вася-алкаш, Петя-алкаш или соседская собака, которая тоже бухает. Ему похуй! Главное, чтобы у слушателя была нужная дырка (интерфейс), в которую можно орать. Это и есть слабая связанность, красота!
Смотри, как на Питоне выглядит эта пьянка:
from abc import ABC, abstractmethod
from typing import List
# Это типа ухо, дырка, в которую можно орать. У кого есть такое ухо — тот подписчик.
class IListener(ABC):
@abstractmethod
def update(self, event_type: str, data: any):
pass
# А это наш орущий мудак — Издатель.
class EventManager:
def __init__(self):
self._listeners: List[IListener] = [] # Список тех, кто подписался на его крик
def subscribe(self, listener: IListener):
self._listeners.append(listener) "Прикрутил ещё одно ухо к своей глотке"
def unsubscribe(self, listener: IListener):
self._listeners.remove(listener) "Отвязал ухо, надоело орать"
def notify(self, event_type: str, data: any):
print(f"nEventManager: ОРУ ВСЕМ, ЧТО ПРОИЗОШЛО '{event_type}'!")
for listener in self._listeners:
listener.update(event_type, data) # А тут он конкретно в каждое ухо орёт
# Конкретные ушастые подписчики
class LoggerListener(IListener):
def update(self, event_type: str, data: any):
print(f"Logger: Ага, записал в журнал, что '{event_type}' случилось. Данные: '{data}'.")
class EmailListener(IListener):
def update(self, event_type: str, data: any):
print(f"EmailSender: Ща спам накидаю всем про событие '{event_type}'!")
# Ну и поехали, блядь!
manager = EventManager()
logger = LoggerListener()
email_sender = EmailListener()
manager.subscribe(logger) # Логгер прицепил ухо
manager.subscribe(email_sender) # Рассыльщик спама тоже
manager.notify("user_login", {"user_id": 123}) # Издатель орет: "ЮЗЕР ЗАЛОГИНИЛСЯ!"
manager.unsubscribe(email_sender) # Спамеру надоело, он ухо оторвал
manager.notify("order_placed", {"order_id": 456}) # Орёт снова, но спамер уже не слышит!
Когда эту хуйню применять?
- Когда один объект изменился, а куча других должна об этом узнать, но ты не хочешь, чтобы они все друг у друга в жопе сидели.
- Всякие GUI, где кнопка (издатель) орет "меня нажали!", а десять обработчиков (подписчики) тут же начинают суетиться.
- Ну и вообще, для реактивного программирования — модно, блядь.
Чем хорош, сука?
- Связанность слабая, как у алкаша с реальностью: Издателю похуй на конкретных подписчиков.
- Гибкость овердохуищная: Можешь на лету уши прикручивать и отрывать, система не сломается.