DDD, агрегаты и сущности

У меня есть следующая структура объекта домена

Invoice
 - List<Items>
      - Service

В счете-фактуре есть список элементов, и каждый из этих элементов имеет услугу.

Структура БД следующая

Invoices Table
Items Table (fk to invoice, fk to service)
Services Table

Если я правильно понял, счет-фактура является совокупным, элементы являются объектами, а услуга является объектом значения для элемента в этом сценарии?

Что произойдет, если мне нужно добавить новые службы в базу данных. Должен ли я создать новый класс Service, который затем будет агрегирован для этого сценария и иметь собственный репозиторий?


person Robert    schedule 29.06.2016    source источник


Ответы (2)


Invoice
 - List<Items>
      - Service

Первое, на что следует обратить внимание — это описание структуры. Мотивацией агрегатов в DDD является не структура, а поведение. Роль агрегата заключается в обеспечении того, чтобы изменения, внесенные в структуру, соответствовали бизнес-правилам.

Если я правильно понял, счет-фактура является совокупным, элементы являются объектами, а услуга является объектом значения для элемента в этом сценарии?

Близко, но терминология немного более мутная (извините). Если эта структура представляет состояние в границах агрегата, то Invoice будет сущностью, действующей как aggregate root, а сам агрегат обычно будет называться Invoice aggregate.

Items и Service могут быть типами значений или сущностями. Вам нужно больше информации, чтобы знать наверняка. Судя по названиям (которые следует брать из вездесущего языка), они, вероятно, являются обеими сущностями. ServiceName или ServiceId чаще всего являются типами значений.

Важный момент: если это сущности, их жизненные циклы подчинены Invoice. Другими словами, «каскадное удаление» счета приведет к удалению товаров и услуги вместе с ним.

Что произойдет, если мне нужно добавить новые службы в базу данных. Должен ли я создать новый класс службы, который затем будет агрегирован для этого сценария и иметь собственный репозиторий?

Немного наоборот: компонент постоянства поддерживает модель предметной области, а не наоборот.

Если Услуга является объектом, и этот объект имеет жизненный цикл, не зависящий от какого-либо одного счета (например, если два разных счета могут относиться к «одной и той же» Услуге), то объект Услуга должен быть в другом агрегате, чем объект Сервиса. Счет-фактура, а состояние счета-фактуры содержит ссылку на услугу, а не на саму услугу.

Если это правильная модель, то из этого следует, что агрегат службы будет иметь собственный репозиторий.

person VoiceOfUnreason    schedule 29.06.2016
comment
так как услуга может использоваться совместно с несколькими счетами-фактурами, в этом случае объект Item не должен содержать объект Service, а не должен иметь только ServiceId? - person Robert; 29.06.2016
comment
так как услуга может быть разделена между совокупными границами и т. д., да. - person VoiceOfUnreason; 29.06.2016
comment
Это какое-то общее правило или рекомендация из синей книги? - person Robert; 29.06.2016
comment
Да, это следствие обращения с агрегатом как с границей согласованности. См. главу 6 для обсуждения агрегатов. Кроме того, ознакомьтесь с тем, что Эванс говорит об агрегатах в этом выступлении: youtube.com/watch?v= lE6Hxz4yomA - person VoiceOfUnreason; 29.06.2016
comment
Спасибо. Пиво твое :D - person Robert; 29.06.2016

Могут ли Сервисы существовать сами по себе? - похоже, они могут на основе того, что у вас есть выше.

Если вам нужно добавить новые службы в базу данных (и я предполагаю, что служба является автономной), вам необходимо создать совокупный корень службы. Также будет репозиторий службы и т. д. для его добавления.

Совокупные корни и репозитории всегда совпадают друг с другом. Ключевым моментом является понимание того, каковы совокупные корни в вашем домене. Как только вы определите их правильно, репозитории станут самоопределяемыми.

Обратите внимание, что если вам когда-либо понадобится добавить что-то вроде нового элемента в счет-фактуру в приведенном выше примере, вам придется сделать это через репозиторий счетов-фактур. Простая причина этого в том, что Item является сущностью, а не совокупным корнем.

person bstack    schedule 29.06.2016
comment
поэтому должен ли Item содержать ссылку на Service или вместо этого должен быть просто ServiceID? - person Robert; 29.06.2016
comment
По-разному. Но скорее всего в описанной вами ситуации одного ServiceID будет достаточно - person bstack; 30.06.2016