handbookНаписать

lessons/003-events-instead-of-calls/step-2/README.md · тема · 4 языка · 15 тестов

Шаг 2: доменное событие и синхронный диспетчер ​

Checkout публикует OrderPlaced, а склад, аналитика и почта подписываются на него сами.

Урок: События вместо прямых вызовов. Предыдущий шаг: касса зовёт всех сама. Следующий шаг: независимые подписчики.

Что было ​

Checkout получал три сервиса и вызывал их по очереди. Касса знала обо всех реакциях, а тест оформления собирал их все.

Что меняем ​

  • Появляется событие OrderPlaced: неизменяемый факт в прошедшем времени с номером заказа, почтой, товарами и суммой. Слушателю хватает данных события, ему не нужно спрашивать кассу.
  • Появляется EventDispatcher с двумя методами: subscribe (тип события, слушатель) и dispatch (событие). Диспетчер синхронный: зовёт слушателей по очереди в том же процессе.
  • Каждая реакция становится слушателем: RequestPicking, TrackPurchase, SendConfirmation. Это маленькие объекты, которые получают свой сервис и знают, что сделать с событием.
  • Checkout получает только Orders и диспетчер. place сохраняет заказ и публикует событие.

Тесты не меняются по смыслу: меняется только сборка в setUp, где появляются три подписки. Тест с лежащей аналитикой проходит как раньше - ошибка долетает до place, письма нет. Добавлен тест, что касса работает с диспетчером без подписчиков: ей больше не нужна почта, чтобы оформить заказ.

Как это собирается ​

Подписки переезжают из кассы в место сборки приложения: в PHP это сервис-провайдер, в Go - main, в Python и TypeScript - модуль старта. Там создаются клиенты, из них слушатели, и каждый подписывается на OrderPlaced. Касса получает готовый диспетчер и не знает, сколько у него подписчиков. Вывод примера такой же, как на шаге 1: второй заказ без письма и с ошибкой.

Сценарий целиком с выводом: пример на PHP, он же на Go, Python и TypeScript в панели кода.

Что стало лучше ​

  • Checkout не знает о почте, складе и аналитике. Новая реакция - новый слушатель и строка подписки, касса не меняется.
  • Каждую реакцию можно проверить отдельно: дать слушателю событие и посмотреть на его сервис.
  • Событие - явный контракт между оформлением и реакциями. Его поля видно в одном месте.

Что ещё болит ​

  • Ошибка слушателя прерывает dispatch и долетает до place. Лежит аналитика - письма по-прежнему нет.
  • Слушатели зависят от порядка подписки: если подписать почту раньше аналитики, письмо уйдёт. Независимыми они только выглядят.
  • Вызывающий код получает ошибку чужой реакции и не может понять, оформлен заказ или нет.

Запуск: make test T=lessons/003-events-instead-of-calls/step-2

© 2014-2026 Тимур ТурдыевСайт и справочник работают на VPS от AdminVPS