Applying UML and Patterns by Craig Larman has a very brief discussion of the Command-Query Separation Principle. “The principle states that every method should either be:
- a command method that performs an action (updating, coordinting, ...) and is void (no return value); or
- a query that returns data to the caller and has no side effects - it should not permanently change the state of any objects
But - and this is the key point - a method should not be both” - Applying UML and Patterns by Craig Larman (buy it on Amazon).
Essentially, the Command-Query Principle advises that a method should either be a command to tell an object to do something or query the status of an object, but not both. A method that changes (commands) the state of an object should have a return of “void“.
“CQS [Command-Query Principle] is widely considered desirable in computer science theory because with it, you can more easily reason about a program's state without simulataneously modifying that state. And, it make designs simpler to understand and anticipate.” - Applying UML and Patterns by Craig Larman
Let's take the example of an e-commerce website. The method that adds a product to the shopping cart is a command to add a product to the shopping cart. Internally, it either adds a new item to the shopping cart or updates the quantity of an existing item in the shopping cart if the item already exists. The point is that the AddItemToCart(...) method should only perform the operation and not return a value. When you add an item to the shopping cart, you need to query either another method or access a property to determine if a new item has been added to the shopping cart or if the quantity of an item has been updated. Doing both in one query would violate the Command-Query Separation Principle.
It has to do with “Tell vs. Ask.” Either tell and object to do something or ask it for some information, but not both.
“If an application consistently follows the Command-Query Separation, you know that a query of getter method isn't going to modify anything and a command isn't going to return anything.” - Applying UML and Patterns