DDD/NHibernate Использование корня Aggregate и влияние на веб-дизайн — напр. Редактирование дочерних элементов совокупного корня

Надеюсь, этот вымышленный пример проиллюстрирует мою проблему:

Предположим, вы пишете систему, которая отслеживает жалобы на программный продукт, а также многие другие атрибуты продукта. В этом случае SoftwareProduct — это наш совокупный корень, а жалобы — это объекты, которые могут существовать только как дочерние элементы продукта. Другими словами, если программный продукт удаляется из системы, то и жалобы тоже.

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

Возникает вопрос: как лучше всего экрану редактирования получить одну жалобу, чтобы ее можно было отобразить для целей редактирования? Имейте в виду, что мы уже установили SoftwareProduct как совокупный корень, поэтому прямой доступ к жалобе не должен быть разрешен. Кроме того, система использует NHibernate, так что немедленная загрузка является вариантом, но я понимаю, что даже если одна жалоба загружается через SoftwareProduct, как только осуществляется доступ к коллекции жалоб, загружается остальная часть коллекции. Итак, как же получить единственную жалобу через SoftwareProduct, не неся накладные расходы на загрузку всей коллекции жалоб?


person Pat    schedule 21.11.2009    source источник


Ответы (5)


Я использую NH для другого бизнес-контекста, но с такими же отношениями сущностей, как у вас. Я не понимаю, почему ты говоришь:

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

У меня так в моих, Article и Publisher сущностях, если Publisher перестанет существовать, то и все зависимые Artcle сущности. Я позволяю себе иметь прямой доступ к Article коллекциям каждого Publisher и отдельных сущностей. В базе данных/отображении класса Article Publisher является одним из членов и не может принимать Null.

Хотите уточнить разницу между вашим и моим?

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

person o.k.w    schedule 21.11.2009
comment
Я определенно не эксперт по DDD, но я понимаю, что одна из основных концепций совокупного корня заключается в том, что дочерними сущностями следует управлять только через корень. Я мог что-то неправильно понять, но я видел это правило во многих местах. Эта ссылка также обсуждает концепцию совокупных корней. dddstepbystep.com/wikis/ddd/ я думаю ситуации одинаковы, поэтому вы должны использовать репозиторий статей для получения конкретной статьи, которая затем также будет иметь издателя? - person Pat; 21.11.2009
comment
@pbrophy: Да, я получаю определенную статью в своем приложении. В вашем случае, если SoftwareProduct — это ОГРОМНАЯ сущность со многими другими членами, вы можете добавить определенные проекции/преобразователи, чтобы не загружать всю сущность, а только те, которые вам нужны. - person o.k.w; 21.11.2009
comment
Итак, когда вы возвращаете статью, вы редактируете элементы через статью или издателя. Другими словами, вы говорите: Publisher.Articles[0].Title = New Title PublisherRepository.Save(Publisher) ИЛИ Article.Title = New Title ArticleRepository.Save(Article) - person Pat; 21.11.2009
comment
@pbrophy: Да, я использую Article.Title = "New Title", а затем ArticleDAL.Update(Article) - person o.k.w; 21.11.2009

Это немного затрагивает семантику и религиозность, но в контексте редактирования жалобы жалоба является корневым объектом. При редактировании жалобы родительский объект (программный продукт) не имеет значения. Очевидно, что это сущность с уникальной идентичностью. Следовательно, у вас будет служба/репозиторий, предназначенный для сохранения обновленной жалобы и т. д.

Кроме того, я думаю, что вы слишком негативно настроены. Жалобы? Как насчет «Комментариев»? Или "конструктивная критика"?

person Josh    schedule 21.11.2009

@Джош,

Я не согласен с тем, что вы говорите, хотя я заметил, что некоторые люди разрабатывают свои «веб-приложения» таким образом только ради производительности, а не на основе самой модели предметной области.

Я тоже не эксперт по DDD, но я уверен, что вы читали традиционный пример Order и OrderItem. Во всех книгах DDD говорится, что OrderItem принадлежит агрегату Order, причем Order является корнем агрегата.

Исходя из того, что вы говорите, OrderItem больше не принадлежит агрегату Order, поскольку пользователь может захотеть напрямую редактировать OrderItem с неважным Order (точно так же, как редактирование Complaing с его родительским программным продуктом неважным). И вы знаете, что если следовать этому подходу, ни один из инвариантов Order не может быть применен, что чрезвычайно важно, когда речь идет о системах электронной коммерции.

У кого-нибудь есть лучшие подходы?

Мош

person Mosh    schedule 01.04.2010

Чтобы ответить на ваш вопрос:

Агрегаты используются для обеспечения согласованности. Например, если добавление/изменение/удаление дочернего объекта из родительского (агрегатного корня) приводит к нарушению инварианта, тогда вам нужен агрегат.

Однако в вашей проблеме я считаю, что SoftwareProduct и Compliant принадлежат двум отдельным агрегатам, каждый из которых является корнем своих собственных агрегатов. Вам не нужно загружать SoftwareProject и все назначенные ему N жалоб, просто добавьте новую жалобу. Мне не кажется, что у вас есть какие-либо бизнес-правила, которые нужно оценивать при добавлении новой жалобы.

Таким образом, создайте 2 разных репозитория: SoftwareProductRepository и ComplaintRepository.

Кроме того, когда вы удаляете SoftwareProduct, вы можете использовать отношения базы данных для каскадного удаления и удаления связанных жалоб. Это должно быть сделано в вашей базе данных для обеспечения целостности данных. Вам не нужно контролировать это в вашей модели предметной области, если у вас нет других инвариантов, кроме удаления связанных объектов.

Надеюсь это поможет,

Мош

person Mosh    schedule 13.04.2010

Я согласен с Мошем. Каждая из этих двух сущностей имеет свой собственный совокупный корень. Позвольте мне объяснить это в реальной жизни. Предположим, что компания разработала программное обеспечение. В этом программном обеспечении есть некоторые ошибки, которые вас раздражали. вы собираетесь пойти в компанию и узнать их от этой проблемы. эта компания дает вам форму для заполнения вами.

Эта форма имеет поле - раздел - указывает на название программы и описание. кроме того, в нем есть некоторые части для вашей жалобы. Является ли эта форма такой же, как руководство по программному обеспечению? Нет. Это форма, связанная с программным обеспечением. Это не программное обеспечение. У этой формы есть идентификатор? да. Она имеет. Другими словами, вы можете позвонить в компанию на следующий день и узнать у оператора письмо с жалобой. Очевидно, что оператор спросит вас об Id.

Это свидетельство показывает, что эта форма имеет свою собственную сущность, и ее нельзя спутать с самим программным обеспечением. Любая связь между двумя разными сущностями не означает, что одна из них принадлежит другой.

person Arash    schedule 06.03.2012