Command–query separation
| This article needs additional citations for verification. (February 2008) (Learn how and when to remove this template message) |
Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, Asking a question should not change the answer.[1] More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
Contents
Connection with design by contract[edit]
Command–query separation is particularly well suited to a design by contract (DbC) methodology, in which the design of a program is expressed as assertions embedded in the source code, describing the state of the program at certain critical times. In DbC, assertions are considered design annotations – not program logic – and as such, their execution should not affect the program state. CQS is beneficial to DbC because any value-returning method (any query) can be called by any assertion without fear of modifying program state.
In theoretical terms, this establishes a measure of sanity, whereby one can reason about a program's state without simultaneously modifying that state. In practical terms, CQS allows all assertion checks to be bypassed in a working system to improve its performance without inadvertently modifying its behaviour. CQS may also prevent the occurrence of certain kinds of heisenbugs.
Broader impact on software engineering[edit]
Even beyond the connection with design by contract, CQS is considered by its adherents to have a simplifying effect on a program, making its states (via queries) and state changes (via commands) more comprehensible.[citation needed]
CQS is well-suited to the object-oriented methodology, but can also be applied outside of object-oriented programming. Since the separation of side effects and return values is not inherently object-oriented, CQS can be profitably applied to any programming paradigm that requires reasoning about side effects.[citation needed]
Command query responsibility segregation[edit]
Command query responsibility segregation (CQRS) applies the CQS principle by using separate Query and Command objects to retrieve and modify data, respectively.[2][3]
Drawbacks[edit]
CQS can make it more difficult to implement re-entrant and multi-threaded software correctly. This usually occurs when a non-thread-safe pattern is used to implement the command–query separation.
Here is a simple example of a pattern that breaks CQS principles but is useful for multi-threaded software. It breaks CQS principles because the function both mutates state and returns it:
private int x;
public int increment_and_return_x()
{
lock x; // by some mechanism
x = x + 1;
int x_copy = x;
unlock x; // by some mechanism
return x_copy;
}
Here is a CQS-compliant pattern. However, it is safely usable only in single-threaded applications. In a multi-threaded program, there is a race condition in the caller, between where increment() and value() would be called:
private int x;
public int value()
{
return x;
}
void increment()
{
x = x + 1;
}
Even in single-threaded programs, it is sometimes arguably significantly more convenient to have a method that is a combined query and command. Martin Fowler cites the pop() method of a stack as an example.[4]
See also[edit]
References[edit]
- ^ Meyer, Bertrand. "Eiffel: a language for software engineering" (PDF). p. 22. Retrieved 16 December 2014.
- ^ Young, Greg. "CQRS Documents" (PDF). Retrieved 2012-12-28.
- ^ Fowler, Martin. "CQRS". Retrieved 2011-07-14.
- ^ Fowler, Martin. "CommandQuerySeparation". Retrieved 5 December 2005.
Further reading[edit]
- Meyer, Bertrand (1988). Object-oriented Software Construction. Prentice Hall. ISBN 0-13-629049-3.
External links[edit]
- Explanation on Martin Fowler's Bliki
- CQRS, Task Based UIs, Event Sourcing agh! by Greg Young
- Clarified CQRS by Udi Dahan
- CQRS Journey by Microsoft patterns & practices
- DDD/CQRS/Event Sourcing List
- The CQRS Frequently Asked Questions
- CQRS - a new architecture precept based on segregation of commands and queries
- Little CQRS book a collection of blog posts written by Mark Nijhof about his Fohjin CQRS example project from 2009
- CQRS Starter kit (.NET)
- Axon CQRS Framework for Java
- CS-CQRS - A C# CQRS Framework
- Commercially sponsors of CS-CQRS
- A blog focused on practical CQRS (.NET)