Command Query Separation principle says that your operations should be either commands or queries but not both.
CQS was introduced by Bertnard Meyer back in 80s. Even though CQS was introduced for Object oriented programming, it can, in fact, be applied to functional, procedural or structured programming. CQS can be applied to any operations, not particularly to methods, since it is applicable to different paradigms.
Wikipedia defines the principle as follows:
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
You can also scale out Queries and Commands independently.
We define a Command as an operation that has a side effect. Command is everything that has an observable side effect.
Query on the other hand is an operation that returns data. I am not strictly talking about database; it can be an operation returning data from any data source or from the operation itself.
It is technically possible to write operations that have both side effects and returns data, nothing prevents you doing that in most languages, and therefore CQS is a principle tells you not to do so.
Commands are operations that mutate, change the observable state of the system.
Common characteristics of these methods are they all return void. Then why would you invoke these methods? Because you would expect side effect. If they have no side effect, why would you bother invoking them, right?
Queries on the other than do not modify observable state.
Common characteristics of these methods are they return something. If a method returns something, it must be a query. Query operations are idempotent. If you invoke an operation once or many times, it shouldn’t change the state of the system. Asking the question many times, should not change the answer. It is safe to invoke a query, once or many times.
So it is easy to detect which methods are query and which are commands.
On the other hand you can use queries within commands.
The whole point is that; Just by looking at the method signature, you should understand which methods are commands and which are queries, and thus which has side effect or not.
If you follow CQS across your code base, you will learn to trust your code base and it will be easy to reason about the code. It is also very easy to apply this principle.
Martin Fowler says that CQS is not a principle, it is instead a rather reasonable suggestion. Because it is such a simple concept, for example, you can have two types of classes in your app one for Commands and one for Queries.
Martin Fowler shows one example on the bliki with:
Meyer likes to use command-query separation absolutely, but there are exceptions. Popping a stack is a good example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I’m prepared to break it to get my pop.
CQS becomes much more important when we talk about distributed systems and idempotency. The queries are naturally idempotent. The commands are not naturally idempotent.
Query are generally what we need to scale, in most systems you have more queries than commands.
While queries are easy to scale, commands are hard to scale. Because queries can be eventually consistent.