CQRS
![]() | В статье не хватает ссылок на источники (см. рекомендации по поиску). |
The Command and Query Responsibility Segregation (CQRS) — принцип, или парадигма, CQRS разделяет назначение запросов (например, при чтении данных) и команд на обработку данных. Внедрение CQRS в приложение может максимизировать его производительность, масштабируемость и безопасность. Гибкость, создаваемая переходом на CQRS, позволяет системе лучше развиваться с течением времени и не позволяет командам обновления вызывать конфликты слияния на уровне домена.[1]
Шаблон CQRS применяет принцип императивного программирования разделения команд и запросов — сommand-query separation (CQS), используя отдельные объекты запросов и команд для извлечения и изменения данных соответственно[2][3]. CQS введён Бертраном Мейером во время работы над языком программирования Eiffel. Принцип гласит, что метод должен быть либо командой, выполняющей какое-то действие, либо запросом, возвращающим данные, но не одновременно. Другими словами, задавание вопроса не должно менять ответ. Более формально, возвращать значение можно только чистым (т. е. детерминированным и не имеющим побочных эффектов) методом. Строгое соблюдение этого принципа делает невозможным отслеживание количества вызовов запросов.
Применение в контрактном программировании
[править | править код]CQRS особенно хорошо вписывается в методологию контрактного программирования, в которой используются утверждения, встроенные в исходный код, описывающие состояние программы в определённые важные моменты. В контрактном программировании утверждения относятся к проектированию, а не к логике выполнения, поэтому их выполнение не должно оказывать влияния на состояние программы. CQRS выгоден для контрактного программирования, так как любой возвращающий значение метод (любой запрос) можно вызывать в утверждениях, не беспокоясь о возможном изменении состояния программы.
Теоретически, это даёт возможность узнавать состояние программы, не меняя его. На практике, CQRS даёт возможность пропустить все проверки утверждений в действующей системе, чтобы повысить её производительность, не боясь того, что это изменит её поведение. CQRS также предотвращает возникновение некоторых гейзенбагов.
Другие применения
[править | править код]Даже за пределами контрактного программирования, применение CQRS рассматривается его приверженцами как оказывающее эффект упрощения на программу, делая доступ к её состоянию (через запросы) и изменение её состояния (через команды) более понятными, аналогично тому как избежание использования goto упрощает понимание потока выполнения программы.
CQRS хорошо подходит для методологии объектно-ориентированного программирования, но может быть применён и вне ООП, так как разделение побочных эффектов и возвращения значений не требует ООП, поэтому CQRS может быть с пользой применён в любой парадигме программирования, требующей заботы о побочных эффектах.
Недостатки
[править | править код]CQRS может осложнить создание реентерабельного и многопоточного ПО. Эта проблема обычно возникает при использовании непотокобезопасного шаблона для реализации CQRS.
Простой пример шаблона, нарушающего CQRS, но полезного в многопоточном ПО:
private int x;
public int increment_and_return_x()
{
lock x; // какой-либо механизм блокировки
x = x + 1;
int x_copy = x;
unlock x; // какой-либо механизм блокировки
return x_copy;
}
Распространённый CQRS шаблон, применимый только в однопоточных приложениях:
private int x;
public int value()
{
return x;
}
void increment_x()
{
x = x + 1;
}
Даже в случае однопоточных программ иногда можно утверждать, что значительно более удобно иметь метод, объединяющий запрос и команду. Мартин Фаулер приводит метод стека pop()
в качестве примера.[4]
См. также
[править | править код]Примечания
[править | править код]- ↑ dragon119. CQRS pattern - Azure Architecture Center (амер. англ.). docs.microsoft.com. Дата обращения: 1 апреля 2021. Архивировано 20 апреля 2021 года.
- ↑ Young, Greg CQRS Documents . Дата обращения: 28 декабря 2012. Архивировано 24 августа 2014 года.
- ↑ Fowler, Martin CQRS . Дата обращения: 14 июля 2011. Архивировано 29 июня 2015 года.
- ↑ CommandQuerySeparation . Дата обращения: 18 мая 2012. Архивировано 28 июня 2015 года.
Литература
[править | править код]- Bertrand Meyer. Object-oriented Software Construction (неопр.). — Prentice Hall, 1988. — ISBN 0-13-629049-3. (англ.)