Я хотел бы узнать некоторые детали отношений между обработчиками команд, агрегатами, репозиторием и хранилищем событий в системах на основе CQRS.
То, что я понял до сих пор:
- Обработчики команд получают команды от шины. Они несут ответственность за загрузку соответствующей совокупности из репозитория и вызов логики домена в совокупности. После этого они удаляют команду с шины.
- Агрегат обеспечивает поведение и внутреннее состояние. Государство никогда не является публичным. Единственный способ изменить состояние - это использовать поведение. Методы, моделирующие это поведение, создают события из свойств команды и применяют эти события к агрегату, которые, в свою очередь, вызывают обработчики событий, которые соответствующим образом устанавливают внутреннее состояние.
- Репозиторий просто позволяет загружать агрегаты по определенному идентификатору и добавлять новые агрегаты. В основном, репозиторий связывает домен с хранилищем событий.
- Хранилище событий, но не в последнюю очередь, отвечает за хранение событий в базе данных (или в любом другом хранилище) и перезагрузку этих событий в виде так называемого потока событий.
До сих пор так хорошо. Теперь есть некоторые проблемы, которые я еще не получил:
- Если обработчик команды должен вызывать поведение в еще существующем агрегате, все довольно просто. Обработчик команд получает ссылку на репозиторий, вызывает его метод loadById и возвращается суммарный результат. Но что делает обработчик команд, когда еще нет агрегата, но нужно создать? По моему мнению, совокупность должна быть позже перестроена с использованием событий. Это означает, что создание агрегата выполняется в ответ на событие fooCreated. Но чтобы иметь возможность хранить любое событие (включая fooCreated), мне нужен агрегат. Поэтому это выглядит как проблема с курицей и яйцом: я не могу создать агрегат без события, но единственным компонентом, который должен создавать события, является совокупность. Итак, в основном это сводится к: Как мне создать новые агрегаты, кто что делает?
- Когда агрегат запускает событие, внутренний обработчик событий реагирует на него (как правило, вызывается посредством метода apply) и изменяет состояние агрегата. Как это событие передается в хранилище? Кто инициирует действие "отправить новые события в хранилище/хранилище событий"? Сама совокупность? Репозиторий, наблюдая за агрегатом? Кто-то, кто подписался на внутренние события?...?
- И последнее, но не менее важное: у меня проблема с пониманием концепции потока событий правильно: в моем воображении это просто нечто вроде упорядоченного списка событий. Что важно, так это то, что он "приказал". Правильно ли это?