Репозиторий, сервис или объект домена - где логика?

Возьмем этот простой надуманный пример:

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);

person betitall    schedule 04.06.2010    source источник


Ответы (3)


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

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

person Bryan Watts    schedule 06.06.2010

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

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

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

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

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

person Joel Cunningham    schedule 04.06.2010
comment
В ответ на ваш последний абзац: что, если сохранение изменения - это единственная логика. например ActivateUser () просто обновляет одну запись в таблице User и одну запись в таблице ActivationCode. Это логика? Если нет, то что делает? - person betitall; 06.06.2010

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

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

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

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

person Szymon Pobiega    schedule 07.06.2010