DDD: отношение «один ко многим» между корнем пользовательского агрегата и почти всеми сущностями в других агрегатах.

У меня есть следующий сценарий DDD, сгруппированный в следующие агрегаты:

Пользователь,
Друзья (ассоциации пользователей),
Файл (для загрузки пользователем),
Галереи (группировка файлов),
Сообщения (общение пользователей),
Группы (пользователи могут создавать и другие участники могут присоединиться),
GroupMessages (сообщения, отправляемые всем членам группы),
GroupForums (участники группы могут обсуждать различные темы)

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

Кажется, что я не должен добавлять все связи «один ко многим», которые существуют здесь, к пользовательскому объекту, поскольку гидратация из базы данных кажется нелепой, особенно если я попытаюсь вытащить каждую запись, связанную с пользователем. Какова рекомендуемая стратегия для организации ваших агрегатов и репозиториев, а также правильный способ работы с большим количеством отношений «один ко многим» для данной сущности?


person user1790300    schedule 04.05.2013    source источник


Ответы (1)


Тот факт, что вы использовали слово «связанный» в своем предложении «Пользователь связан со всем ...», является подсказкой. Совершенно нормально, когда совокупные корни связаны или даже «принадлежат» друг другу. Однако вам нужно посмотреть, может ли сущность существовать без AR. Если это возможно, у него, вероятно, есть собственный жизненный цикл, и он должен быть дополненной реальностью. Если не может, то является частью совокупности. Это может быть сложно перегнать.

У вас должна быть очень четкая граница вокруг ваших AR. Например, хотя Форум может потребовать от Пользователя его создания, это не означает, что Форум нужно (или даже можно) удалить при удалении пользователя. Таким образом, пользователь на форуме может стать, скажем, ForumCreator (объектом значения), который содержит только имя пользователя и идентификатор. После удаления пользователя форум может продолжить свое существование.

В сценарии Order/OrderLine/Product нет особого смысла удалять все строки заказа, содержащие определенный продукт, если вы решите его удалить. Я знаю, что продукт, вероятно, никогда не следует удалять, но мы будем использовать его в качестве примера. Вы бы просто «денормализовали» соответствующие данные о продукте в строке заказа, например: идентификатор продукта, название продукта. Таким образом, даже если название продукта изменится, это не означает, что все строки заказа нуждаются в обновлении или даже должны быть обновлены. На самом деле строка заказа представляет собой момент времени, и «исходное» название продукта должно быть сохранено. Покупатель мог заказать «Some lirril product», а затем название изменилось на «Little product». Не то же самое, хотя это точно такой же продукт. Покупатель помнит только оригинал.

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

person Eben Roux    schedule 05.05.2013
comment
Для примера объединения пользователей я использовал утилиту создания сущностей Entity Framework POCO, которая создала объект User и добавила свойства IList‹› для всех сущностей, с которыми у него есть отношения «один ко многим». Кстати, я использую dapper в качестве микроформы. Должен ли я удалить записи свойств IList‹›, поскольку я предпочитаю получать к ним доступ из соответствующих репозиториев? В этом случае следует ли удалить ассоциацию IList (один ко многим) из сущности пользователя и предоставить доступ к группам через GroupRepository вместо пользовательского репозитория? - person user1790300; 06.05.2013
comment
Я действительно не знаю EF, поэтому я не знаю, как правильно манипулировать файлами. Если на то пошло, я не знаю никакого ORM :) --- w.r.t. Пользователь->Группы это будет зависеть от вашего домена, но я предполагаю, что пользователь для группы - это много ко многим, поэтому я бы удалил этот список из пользователя. Возможно, у вас есть либо список идентификаторов групп, к которым принадлежит пользователь, либо некоторый объект-значение (UserGroup), который содержит идентификатор и имя группы. - person Eben Roux; 06.05.2013
comment
Давайте посмотрим на это с точки зрения чистой сущности и совокупности. Каков рекомендуемый подход к организации отношений между пользователем и сущностями «Друзья», «Файл», «Галереи», «Сообщения», «Группы», «Групповые сообщения», «Групповые форумы»? Мне кажется, что не должно быть записей IList в пользовательском объекте для каждого из них, и вместо этого каждый из других объектов должен содержать свойство для пользовательского объекта. - person user1790300; 06.05.2013
comment
Я согласен с тем, что User, вероятно, не должен иметь списков связанных сущностей, но я не согласен с другими сущностями, имеющими User. Вам не нужен экземпляр 1 AR в другом. Вместо этого используйте либо идентификатор связанного AR, либо VO, представляющий AR (будет содержать идентификатор и другие связанные данные). - person Eben Roux; 07.05.2013