Что на самом деле должен делать репозиторий?

15

Я много слышал о шаблоне хранилища, но я совершенно не понимал, что на самом деле должен делать хранилище. Когда я говорю «что на самом деле должен делать репозиторий», меня больше всего интересует, какие методы он должен предоставлять. Например, должен ли репозиторий действительно предоставлять методы CRUD, или он должен предоставлять какой-то другой метод?

Я имею в виду, должны ли репозитории содержать бизнес-логику или они должны просто содержать логику для связи с хранилищем данных и управления объектами, которые должны быть сохранены или загружены?

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

user1620696
источник
4
«должны ли репозитории содержать бизнес-логику» - нет.
Оз
1
Вот мой ответ на связанный вопрос о SO
Эрик Кинг
2
Я думаю , что вы попасться на слове «должен» - хранилище является шаблоном , конкретно, вы говорите , как будто есть способ репо должно быть сделано , что это лучший способ сделать репо; это заблуждение, поскольку есть только один способ сделать репо, все остальное не будет репо. Таким образом, у модели репо есть свои сильные и слабые стороны, но не существует нескольких подходов к репо. Однако существует несколько способов взаимодействия с данными, из которых только один репо. Читайте здесь о некоторых других подходах к взаимодействию с данными
Джимми Хоффа,

Ответы:

13

Хорошо, вы можете увидеть хороший пример в Spring Data Framework, который основан на концепции репозиториев.

Там вы увидите, что репозитории имеют дело только с хранилищем данных и редко содержат какую-либо бизнес-логику (это зарезервировано для уровня обслуживания). Так, например, вы посмотрите на их дизайн, вы увидите, что у них есть интерфейс CRUDRepository, который предоставляет методы для создания, уничтожения и восстановления сущностей (среди прочего). Существует также PagingAndSortingRepository, который добавляет дополнительные функциональные возможности именно для этого, сортировки и подкачки результатов и т. Д., И т. Д.

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

Насколько я знаю, многие из концепций, реализованных в Spring Data Framework, взяты из замечательной книги « Проектирование на основе доменов: решение сложных задач в основе программного обеспечения» , в книге есть целый раздел, посвященный проектированию репозитория.

Вы можете рассмотреть возможность получения его копии.

Небольшая выдержка из книги объясняет:

Шаблон REPOSITORY - это простая концептуальная структура, которая позволяет инкапсулировать эти решения и вернуть фокус нашей модели.

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

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

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

Следовательно:

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

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

edalorzo
источник
4

Он не должен обеспечивать ни прямой интерфейс CRUD, ни бизнес-логику. Он является посредником между бизнес-логикой и базой данных. Интерфейс должен быть в терминах бизнес-логики, но не выполнять саму бизнес-логику, скорее как примитив бизнес-логики. В качестве примера скажем, что вы собирались построить систему электронной почты, у вас есть пользователи и сообщения. Ваш репозиторий будет обеспечивать базовые операции CRUD для пользователей и сообщений, но он также будет предоставлять отфильтрованные представления сообщений, таких как GetUsersNewMessages (пользователь) или GetSearchedMessages (пользователь, searchTerms).

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

stonemetal
источник