Separate Query from Modifier

Functions should either do something or return something, not both.

“A method returns a value but also changes the state of an object.”

CQS (Command Query Separation).

graph LR
    A[func(): result + sideEffect] -->|Refactoring| B[query(): result]
    A --> C[command(): sideEffect]

When to apply (Smells)

  • Unexpected Side Effects: Calling getTotal() also prints an email.

Motivation

  • Predictability: Queries should be safe to call multiple times (idempotent).
  • Separation of Concerns: Calculating vs Acting.

Mechanics (Steps)

  1. Create a query method that returns the value (without side effects).
  2. Create a command method that performs the side effect.
  3. Replace calls to the original method with calls to the command then the query (or vice versa).

Explanation

Problem

checkSecurity(people) returns “Found” AND sends an alert.

Solution

found = isFound(people) (Query) sendAlert() (Command)

Pros and Cons

Pros Cons
  • No side effects in checks
  • More calls
  • Code example

    Typescript

    Before

    After

    PHP

    Before

    After