вложенные сущности, доменные события
вложенные сущности, доменные события
Есть у меня агрегат, содержащий список сущностей, и каждая из этих сущностей содержит список идентификаторов других сущностей.
Мне нужно сохранять все дерево в репозитории.
Но как быть с событиями? Нет проблем, когда я добавляю сущность в агрегат, но должна ли сущность создавать событие, когда она изменяется?
Если так, то должен ли агрегат следить за освобождением событий сущностей, или за это должен отвечать репозиторий?
Мне нужно сохранять все дерево в репозитории.
Но как быть с событиями? Нет проблем, когда я добавляю сущность в агрегат, но должна ли сущность создавать событие, когда она изменяется?
Если так, то должен ли агрегат следить за освобождением событий сущностей, или за это должен отвечать репозиторий?
Re: вложенные сущности, доменные события
работа с сущностями агрегата ведется через api корня агрегата. Поэтому изменив сущность, мы генерим событие в корне.
Re: вложенные сущности, доменные события
А если это не удобно?
Код: Выделить всё
$aggregate->addSomething($entityId, $itemId)
// намного удобней так
$entity = new Entity(...);
$entity->addSomething(...);
$aggregate->addEntity($entity);
$aggregate->addEntity($entity2);
// ...
$events = $aggregate->releaseEvents(); // обходит сущности и мержит их события со своими
Re: вложенные сущности, доменные события
норм. главное не забывать новые сущности добавлять в обход при добавлении.
Re: вложенные сущности, доменные события
Что-то про время изменения забыл...
Если менять сущность, то агрегат не узнает время изменения напрямую.
Думаю, сделать такой хак. При сохранении, в репозитории выбрать время изменения агрегата и всех сущностей, и в итоге записать максимальное из них. Но в таком случае, $ar->getUpdateTime() будет возвращать не верный результат.
Похоже, нужно будет пробрасывать в entity ссылку на родительский ar.
Как лучше сделать?
Если менять сущность, то агрегат не узнает время изменения напрямую.
Думаю, сделать такой хак. При сохранении, в репозитории выбрать время изменения агрегата и всех сущностей, и в итоге записать максимальное из них. Но в таком случае, $ar->getUpdateTime() будет возвращать не верный результат.
Похоже, нужно будет пробрасывать в entity ссылку на родительский ar.
Как лучше сделать?
Re: вложенные сущности, доменные события
А еще лучше, в методе getUpdateTime агрегата проходить по всем сущностям и возвращать нужное время.
Вроде самый адекватный вариант.
Вроде самый адекватный вариант.
Re: вложенные сущности, доменные события
А почему не хотите события через синглтон EventPublisher::instance() посылать? У Вернона в примерах именно так.
Используя AggreateRoot:releaseEvents() вы создаете тесную связь с бизнес-методами агрегата. То есть агрегат становится не самостоятельным объектом, а зависимым от того, релизнет ли внешний клиент его события или нет. Если сделать через синглтон, проблема с "мерджингом" даже не появится. Откуда вообще эта идея с releaseEvents()?
Re: вложенные сущности, доменные события
Почему? Нету такой зависимости. Релизится в репозитории.
Я про версию синглтона мало чего знаю. Скажи, это просто пул событий? Если так, то как различаются события разных агрегатов?
Идею с releaseEvents позаимствовал у Димы.
Re: вложенные сущности, доменные события
- В синглтоне всё равно придётся собирать в массив (или транзакцию) и вызывать release(), чтобы события выбрасывались после транзакции сохранения.
- В случае накопления в таблицу БД нужно весь код создания и модификации сущностей заключать в общую транзакцию.
- В каждом тесте нужно будет дёргать этот синглтон для проверки событий и каждый раз очищать его в setUp().
Re: вложенные сущности, доменные события
От событий, которые обрабатываются без предварительной записи в таблицу в той же транзакции мало пользы - что если обработчик события зафейлится? Нет никаких шансов на повторение обработки. Событие то больше не придет. А по ним делается репликация в индекс, например.
Re: вложенные сущности, доменные события
Пример можно посмотреть здесь https://github.com/VaughnVernon/IDDD_Sa ... .java#L121.