Все примеры в Интернете имеют основные 4 грубых метода.
Я действительно запутался, как большая система будет реализовывать шаблон репозитория. Допустим, у меня есть пользователь, который принадлежит к группам и пишет книги.
Иногда мне нужны только данные пользователя, иногда данные его книг, а иногда и данные групп. Должен ли я реализовать метод для каждого из вариантов использования?
А как абстрагировать обновления? Если я использую MongoDB, то у меня есть $inc
, $pull
и другие замечательные операторы.
Как мне на самом деле абстрагироваться от этих типов обновлений, если мне нужно их комбинировать, например $set
с $inc
. Нужно ли иметь отдельный метод для каждого варианта использования системы?
В моем случае я создаю один репозиторий для одного агрегата и один метод хранения. В методе хранилища я обновляю различия между сохраненными данными и измененным объектом. Когда нет сохраненных данных, я делаю Insert. Репозиторий агрегата также будет управлять CRUD для дочерних элементов, которые имеют отношения родитель-потомок с агрегатом. Подробная реализация может разделить классы.
Иногда мне нужны только данные пользователя, иногда данные его книг, а иногда и данные групп. Должен ли я реализовать метод для каждого из вариантов использования?
Это, конечно, возможно.
Одним из интересных подходов для рассмотрения является CQRS, который создает явное разделение между «схемами, которые мы используем для изменения информации» и «схемами, которые мы используем для сообщения информации».
Для изменений мы, безусловно, хотим загрузить информацию в представления, которые можно использовать для обеспечения сохранения инварианта динамики нашей области.
Однако для отчетов это не так важно. На самом деле часто бывает так, что (для отчета) нам нужен только фрагмент информации, используемой в логике нашей предметной области, а не весь граф информации. В этом случае имеет смысл использовать другой протокол для преобразования протокола запроса в интересную и полезную структуру данных.
Кроме того, ваши операции чтения и записи могут вообще не использовать общую информацию — может быть лучше генерировать отчеты из кэшированных копий информации (например, в обмен на некоторую свежесть данных в обмен на меньшую задержку).
Частью смысла REPOSITORY является то, что он действует как граница инкапсуляции, отделяя систему управления информацией от компонентов вашего решения, которым просто все равно.
А как абстрагировать обновления? Если я использую MongoDB, то у меня есть $inc, $pull и другие замечательные операторы.
Выберите подходящий уровень абстракции.
Если возможности монго или подобные монго являются необходимым ограничением при выборе постоянного хранилища, то возможность обнаружить это из интерфейса репозитория — это хорошо.
Если эти возможности проявляются только в нескольких путях кода, то, вероятно, у вас будет несколько доступных методов — набор методов для тех путей, которым не нужны дополнительные возможности, которые вы получаете от монго, и другой набор методов. для тех путей, которые делают.
Не могли бы вы поделиться примером того, что вы сделали? Я имею в виду управление CRUD для дочерних элементов, которые имеют отношения родитель-потомок с агрегатом.