Репозиторий, Объект службы или Объект области - где логика принадлежит?

Возьмите этот простой, изобретенный пример:

UserRepository. GetAllUsers (); UserRepository. GetUserById ();

Неизбежно, у меня будут более сложные "запросы", такие как:

//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();

Я испытываю затруднения при определении, где ответственность репозитория заканчивается. GetActiveUsers () представляет простой "запрос". Это принадлежит репозитория?

Как насчет чего-то, что включает немного логики, такой как:

//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);
8
задан betitall 4 June 2010 в 22:14
поделиться

3 ответа

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

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

3
ответ дан 5 December 2019 в 20:14
поделиться

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

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

Если я решаю использовать сервисный слой, я назначаю ему роль обработки транзакций и авторизации. Мне нравится, чтобы он был "тонким" и не содержал никакой доменной логики. Он становится API для моего приложения. Я храню всю бизнес-логику вместе с доменными объектами. Это включает алгоритмы и валидацию объекта. Хранилище извлекает и сохраняет доменные объекты. Для простых систем это может быть отображение один к одному между столбцами базы данных и свойствами домена.

Я думаю, что GetAtcitveUsers подходит для репозитория. Вы не захотите получать всех пользователей из базы данных и выяснять, какие из них активны в приложении, так как это приведет к снижению производительности. Если ActivateUser имеет бизнес-логику, как вы предполагаете, то эта логика принадлежит объекту домена. За сохранение изменений отвечает уровень репозитория.

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

3
ответ дан 5 December 2019 в 20:14
поделиться

При создании проектов DDD мне нравится разделять две обязанности: репозиторий и поисковик.

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

Finder отвечает за запросы к объектам предметной области для целей пользовательского интерфейса, таких как представления сетки и представления деталей.

Я не считаю, что специалисты по поиску являются частью модели предметной области. Конкретные интерфейсы IXxxFinder размещаются на уровне представления, а не на уровне домена. Реализация IXxxRepository и IXxxFinder размещается на уровне доступа к данным, возможно, даже в одном классе.

2
ответ дан 5 December 2019 в 20:14
поделиться