CQRS (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]

Примечания

[править | править код]
  1. dragon119. CQRS pattern - Azure Architecture Center (амер. англ.). docs.microsoft.com. Дата обращения: 1 апреля 2021. Архивировано 20 апреля 2021 года.
  2. Young, Greg CQRS Documents. Дата обращения: 28 декабря 2012. Архивировано 24 августа 2014 года.
  3. Fowler, Martin CQRS. Дата обращения: 14 июля 2011. Архивировано 29 июня 2015 года.
  4. CommandQuerySeparation. Дата обращения: 18 мая 2012. Архивировано 28 июня 2015 года.

Литература

[править | править код]
  • Bertrand Meyer. Object-oriented Software Construction (неопр.). — Prentice Hall, 1988. — ISBN 0-13-629049-3. (англ.)