Являются ли репозитории в DDD единственным типом классов, которые могут касаться персистентности?

В DDD совокупные корни сохраняются через репозитории. Но являются ли репозитории единственными классами, которые могут коснуться персистентности в ограниченном контексте?

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

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

Если такие постоянные классы действительно нужны. Как их назвать, к какому слою они должны принадлежать?

[Обновлять]

Когда я прочитал ответы ниже, я понял, что мой вопрос немного двусмысленный. Под прикосновением я в основном имею в виду запись (включая чтение).

Спасибо.


person foresightyj    schedule 29.02.2016    source источник
comment
Я считаю, что нужно быть прагматичным, а не догматичным. Если вам нужно сохранить события, вы сохраняете события. Однако вам не нужен репозиторий, поскольку репозитории предназначены только для агрегатов. Вы можете отправлять свои события в шину сообщений и сохранять их в каком-то отдельном процессе. Но на самом деле запросы - это запросы, они не могут ничего сохранять по умолчанию, кроме случаев, когда вы хотите что-то там записать. Запросы идемпотентны, они не меняют состояния и не имеют побочных эффектов.   -  person Alexey Zimarev    schedule 29.02.2016
comment
@AlexeyZimarev Я понимаю, что вы сказали о сохранении событий. Также я понимаю, что запросы не должны менять состояния. Но как насчет того, что меняет состояния, но неудобно моделировать их как объекты значений в совокупном корне, например, количество просмотров и голосов?   -  person foresightyj    schedule 01.03.2016
comment
@AlexeyZimarev Наверное, такие вещи, связанные со статистикой, должны быть в отдельном ограниченном контексте? В этом случае я могу использовать более простую архитектуру (например, сценарий транзакции) для управления голосами за и подсчетом просмотров.   -  person foresightyj    schedule 01.03.2016
comment
Трудно что-либо сказать, не имея возможности видеть ваши домены. Если вы возьмете SO, голоса за будут важными атрибутами вопросов и ответов. Что у вас - не знаю. Если вам неловко держать их в составе своей совокупности, возможно, их стоит убрать.   -  person Alexey Zimarev    schedule 01.03.2016


Ответы (2)


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

Не обязательно. CQRS не указывает

  • должна ли модель чтения быть материализована в собственной базе данных
  • как обновляется модель чтения

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

Здесь вы можете увидеть минималистичную, но полностью совместимую с CQRS реализацию: https://github.com/gregoryyoung/mr/tree/master/SimpleCQRS

Но являются ли репозитории единственными классами, которые могут коснуться персистентности в ограниченном контексте?

Нет, в контексте CQRS, Read Model Facades (также известные как репозитории на стороне чтения) также может читать из него, а ваш механизм обновления модели чтения записывает в него.

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

Событийные магазины - это основная технология хранения событийных систем. Вы можете использовать их для хранения нескольких событий домена на стороне в приложении, отличном от ES, но они могут быть излишними и слишком сложными для задачи. Это зависит от того, нужны ли вам все гарантии, которые они предлагают с точки зрения доставки, согласованности, параллелизма / управления версиями и т. Д. В противном случае обычное хранилище СУБД или NoSQL может помочь.

person guillaume31    schedule 29.02.2016
comment
Я понимаю, что хранилище для чтения и запись в БД могут быть отдельными или совместно использовать одну и ту же БД. Сторона запроса может обновлять хранилище для чтения после получения событий домена. Но я вижу хранилище для чтения (если оно отдельное) как дублированный источник данных. Настоящая копия все еще находится в базе данных записи. Но может ли запрос напрямую управлять обновлениями таких мелких вещей, как голоса за, количество кликов (без ведома команды)? - person foresightyj; 01.03.2016
comment
Такие вещи, как голоса за, счетчик кликов, должны где-то храниться, и кто-то должен ими управлять. Но если это будет работа на стороне команды, и в этом случае только репозитории могут писать в db; или это должна быть работа стороны запроса? - person foresightyj; 01.03.2016
comment
Нет, единственная цель репозитория - сохранять агрегаты. Он не должен сохранять данные, специфичные для запроса. Вычисление и сохранение моделей чтения должны выполняться в специальном объекте на стороне запроса. - person guillaume31; 01.03.2016
comment
Вы имеете в виду, что количество просмотров может напрямую управляться (как обновляться, так и считываться) на стороне запроса? - person foresightyj; 02.03.2016
comment
Если количество просмотров (то есть агрегированное общее количество просмотров), конечно, является денормализованными данными на стороне запроса. - person guillaume31; 02.03.2016

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

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

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

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

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

кроме того, почему стороне запроса не разрешено использовать репозитории? Репозитории используются не только для хранения данных. Они также используются для его извлечения. Как вы получаете объекты без репозиториев (даже если вы их не изменяете?)

person Kaidjin    schedule 29.02.2016