In this lesson, you will learn how to improve the predictability of your code by strictly separating methods that change data from those that simply report on it.
The Problem: Mixing Concerns
In many C# classes, you might find a method that does two things: it performs an action (like updating a database) and returns a result. While this seems convenient, it creates "side effects." If you call a method just to see if an item is in stock, but that method also increments an "access count" or modifies a hidden variable, your system becomes unpredictable and hard to debug.
The Solution: Command-Query Separation (CQS)
The Command-Query Separation principle states that every method should be one of two things:
- A Command: Performs an action that changes the state of the system. Commands should return
void. They do one thing and do it well. - A Query: Returns data but does not change the state of the system. Queries should be side-effect-free; calling them a hundred times should never change the underlying object's data.
Practical Example
Imagine an InventoryManager class. Instead of a method that checks stock and marks it as "checked" in a log, we split them:
public class InventoryManager
{
// COMMAND: Changes state, returns nothing
public void RestockItem(string itemId, int amount)
{
// Update database logic here
}
// QUERY: Returns data, does NOT change state
public int GetStockCount(string itemId)
{
return _database.FetchCount(itemId);
}
}
By following this rule, developers using your class can safely call GetStockCount as often as they like without worrying about accidentally triggering a database update or changing a value in the background.
When your code strictly separates "doing" from "asking," your system becomes much easier to test, scale, and maintain because you always know exactly what a method is doing the moment you read its signature.
Key Takeaway: A method should either perform an action (Command) or return data (Query), but it should never do both.