<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Дима пишет | Дмитрий Смотров: заметки с тегом CQRS</title>
<link>https://dimasmotrov.ru/tags/cqrs/</link>
<description>backend python fastapi django rabbitmq kafka postgresql sqlalchemy</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.3 (v4134)</generator>

<itunes:subtitle>backend python fastapi django rabbitmq kafka postgresql sqlalchemy</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>CQRS (3)</title>
<guid isPermaLink="false">12</guid>
<link>https://dimasmotrov.ru/all/cqrs-3/</link>
<pubDate>Fri, 06 Dec 2024 19:48:09 +0300</pubDate>
<author></author>
<comments>https://dimasmotrov.ru/all/cqrs-3/</comments>
<description>
&lt;p&gt;&lt;b&gt;Когда полезно использовать&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;— В сложных доменных областях. Использование подхода позволит снизить сложность каждого конкретного контекста программы.&lt;br /&gt;
— Если в системе сильно различается частота запросов на чтение и запросов на БЛ составляющие системы. Например можно разместить Command &amp; Queries в разных процессах, что позволит горизонтально масштабировать Queries часть системы, так как обычно запросов на чтение сильно больше запросов на запись.&lt;br /&gt;
— Если ваша система спроектирована по принципу EDA(Событийно-ориентированная архитектура). Событию системы соотносится конкретная модель данных. Позволяет БЛ не вытекать за пределы обработчика события.&lt;br /&gt;
— Когда вы собираетесь разделить базу данных на БД для записи и БД для чтения. Однако следует учитывать, что при разделение БД так же встает вопрос о конечной согласованности данных в базах.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Когда использование не даст преимуществ&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;— Модели Command &amp; Queries совпадают. В таких случаях лучше использовать совместную(единую) модель.&lt;br /&gt;
— В случае, если доменная область неверно выделена в системе, то использование CQRS только запутает и без того слабо структурированный код.&lt;/p&gt;
</description>
</item>

<item>
<title>CQRS (2)</title>
<guid isPermaLink="false">11</guid>
<link>https://dimasmotrov.ru/all/cqrs-2/</link>
<pubDate>Fri, 06 Dec 2024 19:47:19 +0300</pubDate>
<author></author>
<comments>https://dimasmotrov.ru/all/cqrs-2/</comments>
<description>
&lt;p&gt;Вернемся к основной теме&lt;/p&gt;
&lt;p&gt;В проектах часто вижу, что ORM модель сущности используется во всех контекстах(доменных областях, которые по сути есть в программе, но по факту никто их явно не выделял) системы:&lt;br /&gt;
— как выходное отображение для ответа API;&lt;br /&gt;
— как DTO между разными модулями;&lt;br /&gt;
— для модуля работы с БД(orm модель по логике должно существовать только в рамках этого модуля);&lt;br /&gt;
— как модель для формирования тела сообщения в очередь сообщений.&lt;/p&gt;
&lt;p&gt;В каждом контексте из перечисленных выше используется одна и та же модель, несмотря на то, что данные модели избыточны в каждом случае примерно на 40-50%(цифры вывел эмпирически, сухой статистики у меня нет, к сожалению). Имеем жирную модель данных на все случаи жизни.&lt;/p&gt;
&lt;p&gt;CQRS предоставляет разделение жирной модели на Command model(модель для работы БЛ: создание, обновление, связывания с моделями других сущностей, и т. д.) &amp; Query Model(отображаемая пользователю в запрашиваемом домене).&lt;/p&gt;
&lt;p&gt;Названия украдены из концепции Command Query Separation (&lt;a href="https://martinfowler.com/bliki/CommandQuerySeparation.html),"&gt;https://martinfowler.com/bliki/CommandQuerySeparation.html),&lt;/a&gt; ключевая идея которой в том, что требуется разделять действия над моделью на две категории:&lt;br /&gt;
— Queries — возвращает результат, но не меняет состояние системы(методы без сторонних эффектов)&lt;br /&gt;
— Command — Изменяет состояние системы, но не возвращает состояние системы.&lt;/p&gt;
&lt;p&gt;Для каждой категории действий над сущностями приложения мы имеем конкретные модели. Если меняется логика создания сущностей — мы актуализируем модель для Command категории. Если меняется логика отображения пользователю — мы актуализируем модель для Query.&lt;/p&gt;
&lt;p&gt;Для каждой категории действии может быть несколько моделей с более конкретной направленностью под каждую доменную область(например списочная и информационная модель из примера в прошлом посте).&lt;/p&gt;
</description>
</item>

<item>
<title>CQRS (1)</title>
<guid isPermaLink="false">10</guid>
<link>https://dimasmotrov.ru/all/cqrs-1/</link>
<pubDate>Thu, 14 Nov 2024 23:50:02 +0300</pubDate>
<author></author>
<comments>https://dimasmotrov.ru/all/cqrs-1/</comments>
<description>
&lt;p&gt;Или же Command Query Responsibility Segregation&lt;/p&gt;
&lt;p&gt;Вообще, идея концепции состоит в разделение моделей данных на модели для чтения и на модели для записи. Но, как мне кажется, лучше смотреть чуть шире:&lt;br /&gt;
каждый контекст системы должен обладать своим собственным состоянием, на каждое состояние необходима своя модель, содержащая информацию исключительно для работы конкретного контекста.&lt;/p&gt;
&lt;p&gt;Например: представим главную страницу сайта для продажи товаров. На этой странице отображена минимальная информация по товарам — фотография, название, цена. Но при переходе на страницу конкретного товара мы увидем более подробное описание товара, помимо цены, фотографии и названия — остаток на складе, производитель, страна поставки сырья и тому подобное.&lt;/p&gt;
&lt;p&gt;Логично, что для отображения товара на главной странице не нужна вся информация о товаре — ее мы посмотрим детально при желании. Отсюда напрашиваются две модели для сущности товара — списочное отображение(минимум данных) и информационное представление(максимум данных).&lt;/p&gt;
&lt;p&gt;Конечно можно использовать только модель для информационного отображения, ведь в ней находятся все данные о товаре, а на главной странице мы можем отображать только необходимый минимум. Но зачем нам кратно увеличивать трафик и сокращать скорость работы главный страницы, когда мы можем этого не делать? К тому же известно, чем больше кода, тем больше вероятность ошибиться: например использовать неверное поле для отображения, допустим вместо title использовать description. Пример смешной и легкий, но если подумать, то сокращение полей в модели снижает риск ошибки, так как поля description в модели не будет вовсе, на главное странице оно не нужно.&lt;/p&gt;
&lt;p&gt;По аналогии с главной страницы товаров, разделение большой(«жирной») модели на более конкретизированные для текущего контекста выполнения позволяет сделать код безопаснее — лишние данные отсутствуют, мы просто обречены использовать именно то, что нужно :)&lt;/p&gt;
</description>
</item>


</channel>
</rss>