Сведения о вопросе

Kirushaa

03:14, 15th August, 2020

Теги

Могу ли я иметь агрегаты "incomplete" в DDD?

Просмотров: 458   Ответов: 5

DDD утверждает, что вы должны получать доступ к сущностям только через их совокупный корень. Так скажем, например, что у вас есть совокупный корень X, который потенциально имеет много дочерних сущностей Y. Теперь, для некоторого сценария, вы действительно заботитесь только о подмножестве этих объектов Y за один раз (возможно, вы показываете их в списке подкачки или что-то еще).

Это OK для реализации репозитория, так что в таких сценариях он возвращает неполный агрегат? То есть. объект X, коллекция Ys которого содержит только интересующие нас экземпляры Y, а не все из них? Это может, например, привести к тому, что методы на X, которые выполняют некоторые вычисления с участием Ys, не будут вести себя так, как ожидалось.

Возможно, это указывает на то, что рассматриваемая сущность Y должна рассматриваться как повышенная до агрегированного корня?

Моя текущая идея (в C#)-использовать отложенное выполнение LINQ, чтобы мой объект X имел IQueryable для представления его отношений с Y. Таким образом, я могу иметь прозрачную ленивую загрузку с фильтрацией... Но заставить это работать с ORM (Linq до Sql в моем случае) может быть немного сложно.

Есть еще умные идеи?



  Сведения об ответе

прога

04:30, 10th August, 2020

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

  1. Разделите свой агрегат на множество более мелких агрегатов. Это означает, что мой первоначальный дизайн не был оптимальным, и мне нужно определить некоторые новые объекты.
  2. Разделите домен на несколько ограниченных контекстов. Это означает, что существуют определенные наборы сценариев, которые используют общее подмножество сущностей в агрегате, в то время как существуют другие наборы сценариев, которые используют другое подмножество.


  Сведения об ответе

fo_I_K

12:46, 23rd August, 2020

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

Книга Джимми Нильссона Глава 6: Подготовка к инфраструктурному запросу. Страница 226.

Шаблон моментального снимка


  Сведения об ответе

PAGE

10:20, 28th August, 2020

Вы действительно задаете два пересекающихся вопроса.

  1. Название и первая половина вашего вопроса - philosophical/theoretical. я думаю, что причина доступа к сущностям только через их "aggregate root" состоит в том, чтобы абстрагироваться от деталей реализации, которые вы описываете. Доступ через aggregate root-это способ снизить сложность, имея доверенную точку доступа. Вы устраняете friction/ambiguity/uncertainty, придерживаясь конвенции. Не имеет значения, как это реализовано в корне, вы просто знаете, что когда вы попросите сущность, она будет там. Я не думаю, что эта перспектива исключает "filtered repository", как вы описываете. Но чтобы обеспечить успешную работу для разработчиков, необходимо создать экземпляр репозитория без явного указания его "filteredness;" точно так же, если возможен общий доступ к экземпляру репозитория, то "filteredness" должен быть явным при кодировании в вызывающем объекте.

  2. Вторая половина вашего вопроса касается реализации на конкретной платформе. Не знаю, почему вы упомянули отложенное выполнение, Я думаю, что это действительно ортогонально вопросу фильтрации. Сама фильтрация может быть немного сложнее реализовать с помощью LINQ. Возможно, вместо того, чтобы вставлять лямбды Where, вы создадите их коллекцию и выберете один в зависимости от необходимого фильтра.


  Сведения об ответе

prince

10:17, 3rd August, 2020

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

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

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


  Сведения об ответе

pumpa

02:53, 23rd August, 2020

Это OK для реализации репозитория тогда, так что в таких сценариях он возвращает неполный агрегат?

Нисколько. Aggregate-это транснациональная граница для изменения состояния вашей системы. Никогда не используйте агрегаты для запроса данных. Разделите систему на стороны записи и чтения. (читайте о CQR & CQRS). Когда мы думаем на основе "CRUD", мы реализуем нашу систему, основанную на каком-то ресурсе. Допустим, у вас есть "Appointment" агрегат. Мышление "Crudish" означает, что мы должны реализовать usecases Create, Update, Delete, GetAll назначения. Это означает, что Appointment[] должен быть возвращен для GetAll. Когда вы думаете, что usecase основан, (HexagonalArchitecture) ваши usecases будут ScheduleAppointment, RescheduleAppointment, CancelAppointment. Но для стороны запроса это может быть: /myCalendar. мы возвращаем все встречи для конкретного пользователя в объекте ClientCalendar. Создайте отдельные DTO для сторон запроса. Никогда не используйте агрегаты для этой цели.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться