Command-query separation
From Wikipedia, the free encyclopedia
| This article does not cite any references or sources. (February 2008) Please help improve this article by adding citations to reliable sources. Unverifiable material may be challenged and removed. |
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. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
Contents |
[edit] Connection with design by contract
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.
[edit] Broader impact on software engineering
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 in a manner reminiscent of how Edsger Dijkstra's admonition against gotos did the same for control flow.
CQS is well-suited to the object-oriented methodology, but can also be applied outside of object-oriented programming. There is nothing inherently object-oriented about the separation of side effects and return values, and so CQS can be profitably applied to any programming paradigm that requires reasoning about side effects.
[edit] Criticism
Some claim that CQS makes it difficult to implement re-entrant and multi-threaded software correctly. This claim usually arises when a non-thread-safe pattern is used to implement the command query separation.
A simple example of a pattern that breaks CQS:
private int x; public int value() { x=x+1; return x; }
A common CQS pattern usable in single threaded applications:
private int x; public int value() { return x; } void increment_x() { x=x+1; }
A CQS pattern suitable for multithreaded environments:
Eiffel language:
x: INTEGER value(ret: TUPLE[value: INTEGER]) is do lock x -- by some mechanism x := x + 1 ret.value := x unlock x -- by some mechanism end
C language:
private int x; public void increment_and_return_x(int *ret) { lock x; // by some mechanism x = x + 1; *ret = x; unlock x; // by some mechanism }
C# language:
Int32 x; void value(out Int32 ret) { lock x; // by some mechanism x = x + 1; ret = x; unlock x; // by some mechanism }
[edit] Further reading
- Meyer, Bertrand (1988). Object-oriented Software Construction. Prentice Hall. ISBN 0136290493.

