#spring-data-jpa #architecture #repository #domain-driven-design
#spring-data-jpa #архитектура #репозиторий #domain-driven-design
Вопрос:
Мне интересно, разрешено ли репозиторию, который сохраняет агрегат A с несколькими объектами, объектами значений, … для доступа к таблицам, содержащим агрегат B. Примером может быть следующее.
Моя система представляет собой веб-магазин, в котором есть несколько продуктов. Product
это совокупный корень, поэтому у меня есть ProductRepository
. Тогда один Order
также является совокупным корнем со своим репозиторием OrderRepository
. Допустим Order
, агрегат включает все OrderLineItems
:
Теперь мой клиент требует раздела в интернет-магазине, в котором показаны продукты, которые никогда не были куплены. В SQL это было бы примерно так:
SELECT * FROM products p
WHERE NOT EXISTS (
SELECT * FROM OrderLineItems o WHERE o.productId = p.id
)
Будет ли разрешен этот запрос ProductRepository
, поскольку он возвращает только Products
или ProductRepository
не может использовать этот запрос, поскольку он обращается к данным другого агрегата?
Ответ №1:
Я бы лично использовал подход, подобный CQRS, для решения такого рода проблем. Используйте агрегаты DDD «только» для «записи», то же самое для классов репозитория.
Создавайте материализованные представления и конкретные модели запросов для материалов, которые не изменяют состояние, например, запрос непроданных товаров, который у вас есть.
Например, вы можете использовать репозитории при изменении состояния (сторона «записи»), например, когда вы сохраняете порядок.
Когда вместо этого вам нужно запрашивать непроданные продукты, у вас может быть специальный обработчик запросов, который запускает прямой запрос к БД (возможно, с использованием облегченной библиотеки, такой как Dapper).
Ответ №2:
- Это, безусловно, разрешено
- Я, вероятно, не стал бы добавлять его в
ProductRepository
себя
Действительно важно отметить, что мы создаем здесь отчет, то есть мы не создаем локальную копию информации, потому что мы намерены изменить эту информацию.
Проблема модели домена — это динамика домена, то есть правила, регулирующие, как данные нашего домена меняются со временем. Если мы не собираемся изменять данные, то, возможно, нам не нужна модель?
Таким образом, вы можете получить фасад, который выглядит как репозиторий, но вместо возврата объекта домена / совокупного корня вместо этого возвращает только необработанные данные, которые вы будете отправлять по сети (например, просто возвращая html, csv или json, которые вам нужны напрямую).
Комментарии:
1. Большое вам спасибо за указание на то, что это разрешено, но может быть не лучшей практикой. Я беспокоился именно о том, что в моем репозитории содержится несколько методов, которые связаны исключительно с потребностями запросов интерфейса. Что меня все еще интересует, так это то, каким будет ваше предлагаемое решение? Я думал о CQRS, чтобы отделить динамику от статического представления.