2008-08-24 5 views
15

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

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

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

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

Любые другие умные идеи?

ответ

1

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

  1. Название и первая половина вашего вопроса являются философскими/теоретическими. Я думаю, что причина доступа к сущностям только через их «совокупный корень» - это абстрагирование тех деталей описания, которые вы описываете. Доступ через совокупный корень - это способ уменьшить сложность, имея надежную точку доступа. Вы устраняете трение/неоднозначность/неопределенность, придерживаясь конвенции. Неважно, как это реализовано в корне, вы просто знаете, что когда вы попросите сущность, он будет там. Я не думаю, что эта перспектива исключает «фильтрованный репозиторий», как вы описываете. Но для предоставления pit of success для разработчиков, которые должны упасть, это должно быть невозможно создать экземпляр репозитория, не будучи явным о его «фильтрации»; аналогично, если возможен общий доступ к экземпляру репозитория, «фильтрация» должна быть явной при кодировании в вызывающем.

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

6

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

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

Это может быть запах кода, но это может быть и не так. У меня такая же проблема. У меня есть класс Trace, который содержит географические путевые точки. Теперь эта трассировка может быть произвольной долготой, и в то время как сама трассировка является сущностью, то путевые точки не являются. Это объекты ценности. Поэтому, если я хочу обновить Trace в чистом DDD-смысле, мне придется загрузить полную совокупную корневую трассировку со всеми ее путевыми точками, добавить некоторые путевые точки и снова сохранить полный трассировку. Это, очевидно, не масштабируется для больших следов. Поэтому из-за проблем с производительностью, с которыми я столкнулся, возможно, чтобы частично загружать агрегированные корни ... – 2012-05-04 09:35:38

2

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

Jimmy Nilsson's book Глава 6: Подготовка к инфраструктуре - запрос. Страница 226.

Snapshot pattern

0

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

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

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