В DDD, как вы работаете с несколькими репозиториями для списков только для чтения - PullRequest
2 голосов
/ 23 марта 2010

Что вы делаете, если вам нужно создать список данных только для чтения на странице, и эти данные, естественно, будут поступать из нескольких, возможно 5 или более разных репозиториев?

Мы используем DDD и форсируем доступ к нашей базе данных через репозитории, но есть сценарий, который не соответствует DDD, и мы пытаемся выбрать оптимальный шаблон для использования.

Например, допустим, у вас есть веб-сайт сообщества с видео, форумами, блогами и т. Д. У вас есть страница форумов со списком комментариев. Это грубо, но я надеюсь, что это имеет смысл.

<table>
<tr><td>User Name (with possible link)</td><td>User's community score.</td><td>User Avatar</td><td>User's E-mail</td><td>User's blog</td><td>User's videos</td></tr>
</table>
<table>
<tr><td>This is a comment.</td></tr>
</table>

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

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

Мое решение состоит в том, чтобы создать DTO UserInformation с соответствующей информацией и поместить метод в репозиторий UserForums с подписью

ILIst<UserInformation> GetUserForumsUserInformationByForumPostID(int forumPostID).

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

Мое собственное мнение состоит в том, что главная цель репозиториев - инкапсулировать бизнес-логику, которая важна для CUD-частей CRUD, но списки только для чтения должны создаваться таким образом, который наиболее целесообразен. Если уместно, я думаю, что даже имеет смысл полностью удалить методы списка, доступные только для чтения, из хранилища (например, в обычном виджете, который используется на страницах разных типов).

Как вы справляетесь с этой ситуацией?

Ответы [ 2 ]

1 голос
/ 24 марта 2010

Ответ № 2

Здесь необходим дополнительный сервисный слой между конкретным хранилищем и клиентом. Иногда то, что нужно клиенту, отличается от того, что обеспечивает уровень хранилища, особенно в случае, когда хранилища могут быть распределены. Сервисный уровень позволяет вам определять грубо детализированные методы и скрывать мелкозернистые детали от клиента. На уровне сервисов вы затем передаете клиенту облегченные DTO вместо полноценных бизнес-объектов.

Чтобы сопоставить бизнес-объекты с DTO и наоборот, инструмент Automapper становится довольно популярным.

1 голос
/ 23 марта 2010

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

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

Согласно Фоверу (PoEAA 401), вы "... обычно не можете переносить объекты из модели предметной области, ... потому что объекты обычно связаны в сложную сеть, которую трудно, если не невозможно, сериализовать. " Фаулер продолжает: «Вместо этого вы должны перенести упрощенную форму данных из объектов домена».

Так что на самом деле, особенно в распределенной системе, передача DTO клиенту является нормой. То, как сервисный уровень собирает эти DTO из доменного уровня, не должно интересовать клиента.

Я должен признать, что меня немного огорчило это высказывание Фаулера. Мне очень нравится удобство использования доменной модели в ASP.Net MVC. Это делает его особенно удобным при создании представлений шаблонов дизайна пользовательского интерфейса. Когда строго типизированное представление связано с клиентом, требуется только строка кода для включения частичного представления CustomerOrders.ascx (с типом IList) и передачи customer.Orders в частичное представление. Может быть, это нормально, если вы продолжаете делать это, пока объект домена не имеет поведения, но это вопрос будущего.

...