Как реализовать хранилище DDD для обработки запроса с несколькими объектами? - PullRequest
3 голосов
/ 29 марта 2011

Я пытаюсь реализовать требование с использованием DDD в решении .net.Я постараюсь минимизировать детали:

Объекты:

  • Категория (UId, Имя)
  • Атрибут (UId, Name, AttributeValues ​​[])
  • AttributeValue (UId, Name, ParentAttributeUId)
  • Процесс (UId, Name, AttributeValues ​​[], Categories [])

Модель данных:

  • Каждый процесс может иметь несколько категорий (например, таблица ProcessCategoryMap)
  • Каждый процесс может иметь несколько значений AttributeValue (например, таблица ProcessAttributeValue)
  • Нет связи между категорией, атрибутами, attributeValues ​​

У меня есть sp FetchByCategoryAndAttributeValues ​​(CategoryId, AttributeValueIds []) Возвращает DataSet:

  • Список процессов, соответствующих CategoryId и AttributeValueIds
  • Список уточнений атрибутаsearch.

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

Есть идеи?

С уважением,

Педро

==== Редактировать: 2011/03/30 14:52 UTC ====

ЯОбновление моего вопроса, чтобы оценить все комментарии, а также помочь другим, сталкивающимся с подобными проблемами.

@ Justice:

решение: Используйте ORM, например, NHibernate, плюс все обоснования использования ORM

Я не помню никаких упоминаний об ORM в книге Эрика Эванса.Какое значение имеет выбор конкретной техники персистенции?После того, как вы разберетесь с доменом, вы сможете сохранить его любым удобным вам способом.Конечно, я знаю, что NH может помочь и является мощным инструментом, но это не решение само по себе.

@ Dominic / @Justice:

Решение: отойдите от процедур хранения.

Прежде всего, мне сложно оправдаться, когда я вижу хороший хранимый T-SQLПроцедура, я не говорю о CRUD или простых запросах T-SQL.SP, о котором я упоминаю, запускает несколько TSQL CTE, объединяет данные метрики из разных таблиц для вычисления весов, используя временные таблицы и возвращает объективные результаты: Список процессов, Список категорий, Список значений атрибутов.SP оптимизирован и настроен для конкретной базы данных / сервера SQL. Это может быть MSFT, Oracle и т. Д. Я не верю, что передача этих вычислений стороне приложения и последующее использование ORM помогли бы сократить время выполнения плюс все назад.и пересылать запросы.Для меня есть большая разница делать все это на сервере и приносить только отфильтрованные данные.Я могу ошибаться.

@ All: Я определил реальную проблему (например, Доменик указывает на ссылку ayende). Я портирую решение, основанное на подходе, ориентированном на данные, на подход с использованием доменной модели.Давайте отложим это, вычисления, возвращаемые SP, влияют на различные Модели.В связи с тем, что данные хранятся в БД, существуют общие вычисления и расчеты ограничены между сущностями, поэтому вопрос о том, как перейти к реализации DDD, заключается в том, как получить лучшую из обеих реализаций.А также как сохранить задания администраторов баз данных :)

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

Спасибо всем, я все еще ищу идеи, ответы и т.д. :)

С уважением, Педро

Ответы [ 4 ]

4 голосов
/ 02 апреля 2011

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

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

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

Решение состоит также в том, чтобы включить архитектуру представления пользовательского интерфейса, такую ​​как MVP или MVC.Объекты домена предназначены для обеспечения соблюдения бизнес-правил в транзакциях - сохранения и обновления.Используйте DTO и Presenters, например, для сборки любого рода «новых» или «гибридных» объектов, которые не представляют знания основной области, а вместо этого конструируются для представления данных пользователю некоторым способом, который хочет пользователь.

В этом случае вы просто создаете DTO, который включает DTO Process и Attribute в новый объект для потребления в пользовательском интерфейсе.

Но есть и другие возможности:

1) Бывают моменты, когда вам приходится спрашивать себя, используете ли вы подходящий инструмент для работы.Я работаю над медицинским приложением, которое имеет очень сложную модель предметной области.Это основное приложение - обеспечение соблюдения сложных правил в процессе сбора данных.Но как только эти данные получены, бизнес заинтересован в том, чтобы делать с ними много разных вещей.Модель сбора данных и аналитическая модель не совсем подходят друг другу, поэтому вместо того, чтобы пытаться заставить их работать вместе, я думаю, что гораздо лучший вариант иметь модель сбора данных, которая является DDD, а затем использовать ETL и перемещать данные в хранилище данных ипредоставьте бизнесу отдельное аналитическое приложение, основанное на запросах, а не на OOP / DDD.

2) Моделирование предметной области - это определение моделей, отражающих истинную область, а не методов реляционных данных.Цель состоит в том, чтобы управлять сложностью и создать модель, которая может быть усовершенствована и изменена по мере изменения бизнеса.Вы не найдете много людей, делающих много DDD, которые даже будут притворяться, что оптимизация является одним из аспектов этого.Напротив, вы строите модель настолько последовательно, насколько это возможно, с DDD.Если вам придется позже, вы компрометируете эту модель настолько, насколько это необходимо, чтобы вывести недопустимую производительность в приемлемый диапазон.

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

Каким бы привлекательным и логичным он ни казался для лучшего из обоих миров, я занимаюсь хардкорными вещами SQL, такими как ETL и хранилище данных, а также DDD.У меня есть некоторые сомнения относительно того, насколько успешно вы можете объединить два мира в одном приложении.Вместо того, чтобы использовать лучшее из обоих миров, есть вероятность, что у вас получится приложение, с которым никто не может работать, и оно тоже не очень хорошо работает.Если у вас есть куча эффективных хранимых процедур, там обязательно будет куча бизнес-логики.Если у вас также есть «объекты», которые имеют бизнес-логику, то в итоге вы получаете бизнес-логику в базе данных, бизнес-логику в «объектной модели», которая оказывается просто (еще одним) приложением, которое имеет классы, но неООП или DDD - почти то же самое, что люди уже делают годами и называют это «n-ярусом».

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

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

.
3 голосов
/ 30 марта 2011

Вам нужно как-то абстрагировать свой код персистентности. Он принадлежит на уровне инфраструктуры, а не на уровне домена (см. DDD стр. 68). Вы можете сделать это вручную, написав код с DataSet s или используя ORM, например, NHibernate.

Если бы вы делали это вручную, шаблон, который я бы порекомендовал, был бы аналогичен тому, который был рассмотрен в практическом исследовании Payroll в Agile Patterns, Practices и Принципы в C # Мартина. Диаграмма вокруг страницы 569 показывает, как он упаковывает компоненты.

1 голос
/ 30 марта 2011

Используйте NHibernate.

Пусть ORM будет вашим хранилищем. Вот для чего.

0 голосов
/ 15 июля 2015

Если вы уже используете Entity Framework, есть несколько способов сделать это (этот ответ частично совпадает с ответом Педро), каждый со своими ограничениями и вариантами использования:

  1. Запрос сущностей EF и возврат DTO.
  2. Запрос SQL напрямую с использованием DBContext's Database.SqlQuery. Если имена ваших свойств DTO совпадают с вашими столбцами SQL, они отображаются для вас.
...