Принципы DDD и дизайн проекта ASP.NET MVC - PullRequest
5 голосов
/ 27 августа 2009

Вопрос из двух частей

У меня есть совокупность продуктов, которая имеет

Цены PackagingOptions ProductDescriptions ProductImages и т.д.

Я смоделировал один репозиторий продуктов и не создавал отдельные репозитории ни для одного из дочерних классов. Все операции с БД осуществляются через репозиторий продуктов.

Правильно ли я понимаю концепцию DDD? Иногда мне приходит в голову вопрос, что наличие репозитория для, скажем, опций упаковки может упростить мою жизнь, напрямую выбирая опцию упаковки из БД с использованием ее идентификатора, вместо того чтобы просить репозиторий продукта найти его в своей коллекции PackagingOptions и это для меня ..

Вторая часть - управление операциями редактирования и создания с использованием фрейма ASP.MVC

В настоящее время я пытаюсь управлять всеми добавлениями, удалением, удалением этих дочерних коллекций продукта через контроллер продукта (правильно?).

Одна проблема, с которой я сейчас сталкиваюсь, это;

Если я редактирую конкретный вариант упаковки продукта через

MYDOMAIN / продукт / editpackagingoption / 10

У меня есть доступ к идентификатору опции упаковки

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

Это очень неправильно ..

Следующая опция, о которой я подумал, - отправка идентификаторов продукта и упаковки в URL-адресе, например;

* * MYDOMAIN тысяча двадцать восемь / продукт / editpackagingoption / 3/10

Но я не уверен, что это тоже хороший дизайн.

Так что я в некотором замешательстве. может иметь фундаментальные недоразумения вокруг всего этого ...

Буду признателен, если вы ответите на длинный вопрос и поможете мне составить это. спасибо!

Ответы [ 2 ]

3 голосов
/ 27 августа 2009

По-моему, это одна из тех грязных вещей, которые появляются в DDD.

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

Например, давайте возьмем пример Customer-> Order-> LineItem-> Product, который к настоящему времени забит до смерти. Совокупный корень, как я показал, является клиентом в этом сценарии. Тем не менее, вы не всегда хотите получить заказ через клиента. Возможно, вы захотите найти заказы на конкретную дату.

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

Дело в том, что вам не нужно загружать клиента через заказ, но вы не обязательно хотите загружать заказ через клиента.

Однако, начиная с Order, маловероятно, что вы захотите просто получить LineItem, и вы, конечно, не собираетесь создавать их без заказа. С этой целью Орден служит шлюзом для LineItems. LineItems не понадобится их собственный контроллер или хранилище. Они существуют только в самом Ордене и, как таковые, являются частью Ордена (в этом случае Орден становится совокупным корнем) и управляются Субъектом Ордена.

Но LineItem, скорее всего, будет иметь отношение к продукту в системе. Продукты будут иметь свои собственные контроллеры, репозитории и т. Д., Потому что они могут существовать вне Агрегированного корня.

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

Может, какой-нибудь пурист DDD поправит меня, если / где я не прав?

Что касается второй части вашего вопроса, мне понадобятся некоторые подробности о том, как вы представляете работу этих других сущностей. С учетом того, что вы здесь разместили, я думаю, что PackagingOptions связаны с продуктом и будут частью объединенного корня продукта. Теперь, подразумевая, что вы редактируете их, напрашивается вопрос, является ли это справочной таблицей в системе, или они являются одноразовыми значениями и, как таковые, должны рассматриваться как объекты-значения?

1 голос
/ 06 апреля 2010

Кайвалья,

Относительно вашего последнего комментария (без сохранения http):

Это зависит от контекста. Прежде чем углубляться в детали, я должен рассказать вам основной принцип об агрегатах:

Агрегаты определяют группу связанных объектов, которые должны рассматриваться как единое целое с целью изменения данных.

Это чрезвычайно важно. Целью наличия Агрегатов является применение инвариантов. Например, у вас может быть политика типа «Заказ не может превышать 500 долларов США». Затем, чтобы применить эту политику, вы объединяете Order и OrderItem вместе в Order Aggregate. Таким образом, каждый раз, когда вы добавляете новый OrderItem, он должен быть добавлен через объект Order. Там вы можете проверить общую стоимость и убедиться, что она не превышает 500 долларов. Если у вас нет таких инвариантов в вашем домене, то нет смысла загружать все эти объекты вместе.

Теперь вернемся к вашему комментарию:

Если у вас есть инварианты, которые должны быть применены, то можно загрузить всю совокупность, даже если она может иметь некоторые накладные расходы. Да, HTTP не имеет состояния, и вы загружаете весь агрегат только для изменения одного из его дочерних объектов, а затем выбрасываете его. Это нормально. Здесь важно то, что вы применяете свои инварианты. Вот для чего DDD.

Цель DDD - захватить всю бизнес-логику в вашем домене. Безусловно, вы могли бы достичь лучшей производительности, если бы вам не нужно было загружать весь агрегат, но как бы вы обеспечили реализацию своих инвариантов? Скорее всего, вам придется сделать это в вашей хранимой процедуре. Да, это работает, и это быстро, но работа с бизнес-логикой в ​​хранимых процедурах во время обслуживания - это кошмар. Вот почему DDD эволюционировал. Таким образом, вы можете моделировать свои бизнес-требования, используя объектно-ориентированные языки / инструменты, чтобы их было легче понять и изменить.

Просто помните, DDD - отличный подход, но не для всех типов проектов. Если вы имеете дело с проектом, в котором есть много бизнес-логик и вероятность их изменения в силу характера бизнеса высока, то вам следует использовать DDD. Тем не менее, если ваш проект представляет собой «чтение / запись чего-либо» без большой бизнес-логики, использование DDD является головной болью. Вы можете просто использовать LINQ to SQL (или SqlDataAdapters) и отправлять свои объекты в ваши представления. Вам даже не нужно беспокоиться о поиске сущностей, объектов-ценностей, агрегатов, репозиториев и т. Д.

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

Мош

...