Страница 1 из 1

вложенные сущности, доменные события

Добавлено: 2018.02.14, 18:17
Bio man
Есть у меня агрегат, содержащий список сущностей, и каждая из этих сущностей содержит список идентификаторов других сущностей.
Мне нужно сохранять все дерево в репозитории.
Но как быть с событиями? Нет проблем, когда я добавляю сущность в агрегат, но должна ли сущность создавать событие, когда она изменяется?
Если так, то должен ли агрегат следить за освобождением событий сущностей, или за это должен отвечать репозиторий?

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 19:32
zelenin
работа с сущностями агрегата ведется через api корня агрегата. Поэтому изменив сущность, мы генерим событие в корне.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 20:58
Bio man
А если это не удобно?

Код: Выделить всё

$aggregate->addSomething($entityId, $itemId)
// намного удобней так
$entity = new Entity(...);
$entity->addSomething(...);
$aggregate->addEntity($entity);
$aggregate->addEntity($entity2);
// ...
$events = $aggregate->releaseEvents(); // обходит сущности и мержит их события со своими

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 21:42
zelenin
норм. главное не забывать новые сущности добавлять в обход при добавлении.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 22:48
Bio man
zelenin писал(а): 2018.02.14, 21:42 норм. главное не забывать новые сущности добавлять в обход при добавлении.
Имеешь в виду в репозитории?

В любом случае, если забуду, то работать не будет. Как ни крути, но такие вещи всплывают сразу, если про них забыть.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 22:56
Bio man
Что-то про время изменения забыл...
Если менять сущность, то агрегат не узнает время изменения напрямую.
Думаю, сделать такой хак. При сохранении, в репозитории выбрать время изменения агрегата и всех сущностей, и в итоге записать максимальное из них. Но в таком случае, $ar->getUpdateTime() будет возвращать не верный результат.

Похоже, нужно будет пробрасывать в entity ссылку на родительский ar.

Как лучше сделать?

Re: вложенные сущности, доменные события

Добавлено: 2018.02.14, 23:11
Bio man
А еще лучше, в методе getUpdateTime агрегата проходить по всем сущностям и возвращать нужное время.
Вроде самый адекватный вариант.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 09:38
anton_z
Bio man писал(а): 2018.02.14, 20:58 $events = $aggregate->releaseEvents(); // обходит сущности и мержит их события со своими[/code]
А почему не хотите события через синглтон EventPublisher::instance() посылать? У Вернона в примерах именно так.
Используя AggreateRoot:releaseEvents() вы создаете тесную связь с бизнес-методами агрегата. То есть агрегат становится не самостоятельным объектом, а зависимым от того, релизнет ли внешний клиент его события или нет. Если сделать через синглтон, проблема с "мерджингом" даже не появится. Откуда вообще эта идея с releaseEvents()?

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 10:29
Bio man
anton_z писал(а): 2018.02.15, 09:38 То есть агрегат становится не самостоятельным объектом, а зависимым от того, релизнет ли внешний клиент его события или нет.
Почему? Нету такой зависимости. Релизится в репозитории.
anton_z писал(а): 2018.02.15, 09:38 Если сделать через синглтон, проблема с "мерджингом" даже не появится. Откуда вообще эта идея с releaseEvents()?
Я про версию синглтона мало чего знаю. Скажи, это просто пул событий? Если так, то как различаются события разных агрегатов?
Идею с releaseEvents позаимствовал у Димы.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 11:11
ElisDN
anton_z писал(а): 2018.02.15, 09:38 Если сделать через синглтон, проблема с "мерджингом" даже не появится. Откуда вообще эта идея с releaseEvents()?
- В синглтоне всё равно придётся собирать в массив (или транзакцию) и вызывать release(), чтобы события выбрасывались после транзакции сохранения.

- В случае накопления в таблицу БД нужно весь код создания и модификации сущностей заключать в общую транзакцию.

- В каждом тесте нужно будет дёргать этот синглтон для проверки событий и каждый раз очищать его в setUp().

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 11:32
anton_z
ElisDN писал(а): 2018.02.15, 11:11 - В случае накопления в таблицу БД нужно весь код создания и модификации сущностей заключать в общую транзакцию.
От событий, которые обрабатываются без предварительной записи в таблицу в той же транзакции мало пользы - что если обработчик события зафейлится? Нет никаких шансов на повторение обработки. Событие то больше не придет. А по ним делается репликация в индекс, например.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 11:34
anton_z
ElisDN писал(а): 2018.02.15, 11:11 - В каждом тесте нужно будет дёргать этот синглтон для проверки событий и каждый раз очищать его в setUp().
Это прям гигантский drawback.

Re: вложенные сущности, доменные события

Добавлено: 2018.02.15, 13:37
anton_z
Bio man писал(а): 2018.02.15, 10:29 Я про версию синглтона мало чего знаю. Скажи, это просто пул событий? Если так, то как различаются события разных агрегатов?
Пример можно посмотреть здесь https://github.com/VaughnVernon/IDDD_Sa ... .java#L121.