- Query. This isn’t a database term, it simply means that the operation should return some data and not have any side effects. Repeated calls to a query should return exactly the same result
- Command. This is an operation that takes some action, it has side effects, it can change your programme state
public ShoppingCart GetShoppingCart();
public void AddItemToShoppingCart(Item item);
GetShoppingCart()is a query, because the signature shows it returns data.
AddItemToShoppingCart()is a command because it returns
Is CQS the same as CQRS?No. They share some terminology but CQS is a programming principle that applies to the methods on an object. Command Query Responsibility Segregation on the other hand is pattern that splits queries and commands into separate models.
Why is CQS useful?I had a lightbulb moment when I read a chapter of Code Complete 2 entitled “Conquer Complexity”. It lists numerous good practices programmers use including writing short methods, writing small classes, using meaningful variable and class names, avoiding deep inheritance hierarchies and breaking up larger systems into smaller sub-systems. The author, Steve McConnell, finishes the chapter with the following:
“A primary goal of software design and construction is conquering complexity. The motivation behind many programming practices is to reduce a program’s complexity”In hindsight I feel a bit stupid. I hadn’t realised that all the these familiar principles served the same purpose, to reduce complexity.
CQS wasn’t listed in that chapter, but it’s no different, it helps reduce complexity. If a code base strictly follows CQS then you can trust an interface without digging into the implementation. If a method returns a value, it’s a query and can be called safe in the knowledge it won’t change anything, no matter how often it’s called. If a method returns void, it’s a command and more care is required.