CQS (Command Query Separation)
Separate commands (side effects) from queries (return data)
“Asking a question should not change the answer.” – Bertrand Meyer
When to use
In every method design, especially in Domain-Driven Design (DDD).
Why it matters
- Predictability: You know that calling
getScore()won’t accidentally increment the score or delete a user. - Testing: Queries are easy to test. Commands can be mocked.
Signs of Violation
- Methods named
getAndIncrement(). - A getter method that modifies internal state (side effect).
Explanation
Problem
If a method returns a value AND changes state, you can’t check the value without changing the state.
Solution
Divide methods into two categories:
- Commands: Void return type. Change state. No side effects? No, only side effects.
- Queries: Return data. Do not change state. Idempotent.
Real world analogy
A distinct inventory count and a sale. Checking “How many shoes?” (Query) shouldn’t sell a shoe. “selling a shoe” (Command) changes the count but usually doesn’t return the inventory (it returns a receipt or nothing).
Pros and Cons
| Pros | Cons |
|---|---|
Comparison
- CQS vs CQRS: CQS is at the method/class level. CQRS is at the architectural/system level.
Code example
Typescript
Bad (Violation)
Good (Adherence)
PHP
Bad (Violation)
Good (Adherence)