Используете несколько сервисов или несколько репозиториев внутри сервиса? - PullRequest
1 голос
/ 11 октября 2019

Представьте, что у нас есть две сущности, EntityA и EntityB. Обе сущности имеют репозиторий для запросов к базе данных, EntityARepository и EntityBRepository. Есть также услуги для них обоих, EntityAService и EntityBService.

Теперь в EntityBService есть метод, который также должен использовать EntityA. Каков будет правильный способ сделать это?

  • Должен ли EntityBService использовать EntityARepository напрямую?
  • Должен ли EntityBService использовать EntityAService?

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

Существует ли общий шаблон дизайна по этой теме или рекомендациям?

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Существует ли общий шаблон проектирования по этой теме или рекомендациям?

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

Таким образом, у нас может быть разумный объект entityA и копия необходимой нам информации от B. Или у нас может быть entityB и копия необходимой нам информации от A.

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

В случае, когда мы используем entityA и recent-copy-of-B, мы знаем, что entityA происходит из репозитория. Откуда взялся recent-copy-of-B? Ну, это происходит из абстракции, которая выглядит как хранилище, за исключением того, что (а) она выбирает значения, а не сущности, и (б) она только для чтения.

recent-copy-of-B выглядит как DTO. И хотя вы можете использовать один и тот же файл везде, на самом деле безопасно (поскольку значения неизменны) создавать специализированные версии для разных вариантов использования.

0 голосов
/ 11 октября 2019

TLDR;это зависит!

Если вы пытаетесь следовать доменно-управляемому дизайну, я думаю, что будет хорошей идеей различать service и repository. Существуют разные определения, которые могут различаться в деталях, но я буду придерживаться определения Мартина Фаулера для Репозиторий :

(...) Репозиторий является посредником между доменом и отображением данныхслои, действующие как коллекция объектов домена в памяти. (...)

и для службы :

Сервисный уровень определяет границу приложения [Cockburn PloP] и его набор доступных операцийс точки зрения взаимодействия клиентских слоев. Он инкапсулирует бизнес-логику приложения, управляет транзакциями и координирует ответы при реализации своих операций.

Стоит отметить, что service это не просто repository + бизнес логика. Для большинства простых сценариев repository просто завершает доступ к одной базе данных, но для сложных сценариев создание одного объекта может потребовать доступа к нескольким базам данных, поэтому роль repository заключается в удалении этого woffle из слоя service.

И вот что вы можете придумать:

  1. Используйте EntityARepository непосредственно в EntityBService, если вы пытаетесь просто получить EntityA без каких-либобизнес логика, связанная с EntityA. Вот простой пример:

EntityBService выполняет операцию с EntityB, но это зависит только от состояния EntityA.

Используйте EntityAService в EntityBService, если запрос EntityA связан с некоторой бизнес-логикой, связанной с EntityA. Вот простой пример:

EntityBService выполняет операции над EntityB и EntityA, и позже его необходимо создать, если он не существует - создание включает в себя бизнес-логику, такую ​​какпроверка разрешена (например, в зависимости от роли пользователя).

...