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:

  1. Commands: Void return type. Change state. No side effects? No, only side effects.
  2. 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
  • Clarity
  • Easier caching (Queries are cacheable)
  • Sometimes requires 2 calls (Do action, then fetch result)
  • 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)