Разработка ПО и Backend систем.

CQRS (2)

Вернемся к основной теме

В проектах часто вижу, что ORM модель сущности используется во всех контекстах(доменных областях, которые по сути есть в программе, но по факту никто их явно не выделял) системы:
— как выходное отображение для ответа API;
— как DTO между разными модулями;
— для модуля работы с БД(orm модель по логике должно существовать только в рамках этого модуля);
— как модель для формирования тела сообщения в очередь сообщений.

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

CQRS предоставляет разделение жирной модели на Command model(модель для работы БЛ: создание, обновление, связывания с моделями других сущностей, и т. д.) & Query Model(отображаемая пользователю в запрашиваемом домене).

Названия украдены из концепции Command Query Separation (https://martinfowler.com/bliki/CommandQuerySeparation.html), ключевая идея которой в том, что требуется разделять действия над моделью на две категории:
— Queries — возвращает результат, но не меняет состояние системы(методы без сторонних эффектов)
— Command — Изменяет состояние системы, но не возвращает состояние системы.

Для каждой категории действий над сущностями приложения мы имеем конкретные модели. Если меняется логика создания сущностей — мы актуализируем модель для Command категории. Если меняется логика отображения пользователю — мы актуализируем модель для Query.

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

Ctrl ←CQRS (1)
Ctrl →CQRS (3)