Перейти к основному содержимому

Что это такое

Паттерн Observer позволяет одному объекту сообщать о событиях многим подписчикам, не зная, кто они. Подписчики регистрируются один раз; после этого каждое событие автоматически доходит до всех.

Издатель зависит только от небольшого интерфейса подписчика — новые виды слушателей появляются без единой изменённой строки в издателе.


Пример: одно оповещение — все подписчики

Монитор хранит массив подписчиков. Когда что-то происходит, он уведомляет весь массив — сегодня это оповещение по электронной почте и панель мониторинга; завтра — сообщение в чат, достаточно его подписать.

Опубликовать один раз, доставить всем

Один вызов alert(), две доставки: письмо на ops@example.com: диск почти заполнен и панель показывает: диск почти заполнен. Монитор понятия не имеет, что такое письмо или панель, — он знает только про объекты, которые можно уведомить.

Prompt
Напишите программу на TypeScript с паттерном Observer: интерфейс Subscriber с методом notify, классы-подписчики EmailAlert и Dashboard, а также издатель Monitor с методами subscribe и alert, который уведомляет каждого подписчика о событии. Подпишите обоих и вызовите одно оповещение.
Вывод: программа на TypeScript и захваченный вывод
Publish once, deliver to all

Когда его применять

Применяйте, когда на одни и те же события должны реагировать несколько частей программы и список реагирующих меняется — обновления интерфейса, оповещения, сброс кеша, ленты активности.

Не применяйте, когда получатель ровно один и он фиксирован — вызывайте его напрямую. И прежде чем писать такой список самому, посмотрите, что уже даёт платформа: в Node.js есть EventEmitter, а в браузерах — EventTarget; и то и другое — этот же паттерн, уже написанный и проверенный.


Плюсы и минусы

Плюсы: издатель и подписчики остаются слабо связанными; подписчики появляются и исчезают во время выполнения; новые реакции не требуют изменений в издателе.

Минусы: поток выполнения становится невидимым — ответ на вопрос «кто на это реагирует?» приходится искать; медленный или падающий подписчик может застопорить цикл уведомлений; забытые отписки приводят к утечкам.