Command-query separation (CQS) або англ. command-query responsibility segregation (CQRS) — це принцип імперативного програмування, винайдений Бертраном Мейером під час роботи над мовою програмування 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().[1]

Див. також ред.

Примітки ред.

  1. CommandQuerySeparation. Архів оригіналу за 28 червня 2015. Процитовано 28 червня 2015.

Література ред.

Посилання ред.