Разделение команд и запросов
Эта статья нуждается в дополнительных цитатах для проверки . ( февраль 2008 г. ) |
Разделение команд и запросов ( CQS ) — это принцип императивного компьютерного программирования . Он был разработан Бертраном Мейером в рамках его новаторской работы над языком программирования Eiffel .
В нем говорится, что каждый метод должен быть либо командой , выполняющей действие, либо запросом , возвращающим данные вызывающему объекту, но не тем и другим. Другими словами, вопрос не должен менять ответ . [1] Более формально, методы должны возвращать значение только в том случае, если они ссылочно прозрачны и, следовательно, не имеют побочных эффектов .
Соединение с проектированием по договору
[ редактировать ]Разделение команд и запросов особенно хорошо подходит для методологии проектирования по контракту (DbC), в которой проектирование программы выражается в виде утверждений, встроенных в исходный код , описывающих состояние программы в определенные критические моменты. В DbC утверждения считаются аннотациями проекта, а не логикой программы, и поэтому их выполнение не должно влиять на состояние программы. CQS полезен для DbC, поскольку любой метод, возвращающий значение (любой запрос), может быть вызван любым утверждением, не опасаясь изменения состояния программы.
Теоретически это устанавливает меру здравомыслия, при которой можно рассуждать о состоянии программы, не изменяя одновременно это состояние. На практике CQS позволяет обойти все проверки утверждений в работающей системе, чтобы повысить ее производительность без непреднамеренного изменения ее поведения. CQS также может предотвращать возникновение определенных видов ошибок Heisenbug .
Более широкое влияние на разработку программного обеспечения
[ редактировать ]Даже помимо связи с проектированием по контракту, его приверженцы считают, что CQS оказывает упрощающее воздействие на программу, делая ее состояния (посредством запросов) и изменения состояний (посредством команд) более понятными. [ нужна ссылка ]
CQS хорошо подходит для объектно-ориентированной методологии, но может применяться и за пределами объектно-ориентированного программирования. Поскольку разделение побочных эффектов и возвращаемых значений по своей сути не является объектно-ориентированным, CQS можно с успехом применять к любой парадигме программирования, требующей анализа побочных эффектов. [ нужна ссылка ]
Разделение ответственности за командный запрос
[ редактировать ]Разделение ответственности за запросы команд ( CQRS ) обобщает CQS для служб на уровне архитектуры: оно применяет принцип CQS, используя отдельные интерфейсы запросов и команд и обычно модели данных для извлечения и изменения данных соответственно. [2] [3]
Другие архитектурные образцы
[ редактировать ]- Отходя от единого представления, с которым мы взаимодействуем через CRUD , мы можем легко перейти к пользовательскому интерфейсу, основанному на задачах.
- CQRS хорошо сочетается с моделями программирования на основе событий. Часто можно увидеть, что система CQRS разделена на отдельные службы, взаимодействующие с Event Collaboration. Это позволяет этим службам легко использовать преимущества архитектуры, управляемой событиями .
- Наличие отдельных моделей поднимает вопросы о том, насколько сложно поддерживать согласованность этих моделей, что повышает вероятность использования конечной согласованности.
- Для многих доменов большая часть необходимой логики требуется при обновлении, поэтому может иметь смысл использовать Eager Read Derivation для упрощения моделей на стороне запроса.
- Если модель записи генерирует события для всех обновлений, вы можете структурировать модели чтения как плакаты событий, позволяя им быть образами памяти и, таким образом, избегая большого количества взаимодействий с базой данных.
- CQRS подходит для сложных доменов, которые также выигрывают от доменно-ориентированного проектирования . [3]
Ограничения
[ редактировать ]CQS может усложнить правильную реализацию реентерабельного и многопоточного программного обеспечения. Обычно это происходит, когда для реализации разделения команды и запроса используется непотокобезопасный шаблон.
Вот простой пример, который не соответствует CQS, но полезен для многопоточного программного обеспечения, поскольку решает сложность блокировки для всех других частей программы, но при этом он не следует CQS, поскольку обе функции изменяют состояние. и возвращает его:
private int x;
public int incrementAndReturnX() {
lock x; // by some mechanism
x = x + 1;
int x_copy = x;
unlock x; // by some mechanism
return x_copy;
}
Вот версия, совместимая с CQS. Обратите внимание, что его безопасно использовать только в однопоточных приложениях. В многопоточной программе в вызывающей программе существует состояние гонки, между которой increment()
и value()
будет называться:
private int x;
public int value() {
return x;
}
void increment() {
x = x + 1;
}
Даже в однопоточных программах иногда гораздо удобнее иметь метод, который представляет собой комбинацию запроса и команды. Мартин Фаулер цитирует pop()
метод стека в качестве примера. [4]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Мейер, Бертран. «Эйфель: язык разработки программного обеспечения» (PDF) . п. 22 . Проверено 16 декабря 2014 г.
- ^ Молодой, Грег. «Документы CQRS» (PDF) . Проверено 28 декабря 2012 г.
- ^ Jump up to: а б Фаулер, Мартин. «ЦКРС» . Проверено 14 июля 2011 г.
- ^ Фаулер, Мартин. «Командный запросSeparation» . Проверено 5 декабря 2005 г.
Дальнейшее чтение
[ редактировать ]- Мейер, Бертран (сентябрь 1994 г.) [1988]. Объектно-ориентированное построение программного обеспечения . Прентис Холл. ISBN 0-13-629049-3 .