Как правильно реализовать шаблон репозитория?

#database #design-patterns #domain-driven-design #clean-architecture

#База данных #дизайн-шаблоны #дизайн, управляемый доменом #чистая архитектура

Вопрос:

Все примеры в Интернете имеют основные 4 метода crud.

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

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

И как абстрагировать обновления? Если я использую MongoDB, то у меня есть $inc $pull и другие замечательные операторы.

Как мне на самом деле абстрагировать эти типы обновлений, если мне нужно их объединить, например $set , с $inc . Нужно ли мне иметь отдельный метод для каждого варианта использования системы?

Ответ №1:

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

Это, безусловно, возможно.

Одним из интересных подходов для рассмотрения является CQRS, который создает явное разделение между «конструкциями, которые мы используем для изменения информации» и «конструкциями, которые мы используем для передачи информации».

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

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

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

Часть смысла РЕПОЗИТОРИЯ заключается в том, что он действует как граница инкапсуляции, отделяя систему управления информацией от компонентов вашего решения, которым просто все равно.


И как абстрагировать обновления? Если я использую MongoDB, то у меня есть $inc, $ pull и другие потрясающие операторы.

Выберите соответствующий уровень абстракции.

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

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

Ответ №2:

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

Комментарии:

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