Command-Query Separation Principle

A few days ago read in Larman's book about Command-Query Separation Principle. Funny to mention  that I heard about the concept many times ago, but this is the only source that stated it as a principle. And it makes total sense once you evaluate all the pros and cons of the idea.

What's the principle? Simple. There are two kinds of messages to objects:

  • Commands - ones that are affecting the state of the object
  • Queries - ones that are querying an object for its' state without affecting its' state at all

A Command message would be "void Calculate()" or "void Add(double value)". Command message never returns a value, and that's for clear separation of the messages and easier maintenance of the object state (i.e. no surprises). A Query message would be what Command isn't "int GetValue()" or "IsVisible()".

One exception the author brought up was internal/private messages that are not a part of the interface, and therefore can violate the principle - I guess this is a matter of personal preference.

An example is an implementation of a Die (for a monopoly game) modified by myself.

    public interface IDie 
{
void Roll();
int GetFaceValue();
}

public class Die : IDie
{
private int faceValue;
private Random rand = new Random();

public void Roll()
{
faceValue = rand.Next(6) + 1;
}

public int GetFaceValue()
{
return faceValue;
}
}

I added the interface on purpose, to have DbC, where implementation doesn't matter that much, because the contract is expressing well enough the intension of how to use an implementer of  an IDie. Thanks to the CQS Principle it becomes crystal clear. It is easy to determine a value of a die, and there's no surprises when a die is queried for it's value.

Now imagine a system with a significant number of components that violate this principle versus a system where components follow it. Can you imagine the difference?

4 Comments

  • This is a perfect example of the side-effect free pattern in domain driven development.

    The big difference between a system that follows this pattern and a system that doesn't, is that you can predict what the results will be when you invoke a method on class in the system that has a side-effect free design.

    I love these kinds of posts, they really show good practice!

  • Hi. I have a question.

    What will happen if I say :
    Die d = new Die();
    int v = d.GetFaceValue();

    v will be zero and zero is not a valid value for a die. Another thing. In .NET I will prefer int GetFaceValue(); to be a property instead of a method. You can define properties in interfaces.

    Just my 2 cents.

  • @Petar
    Yes, you can have properties in C#, but you would use in this getter, and it's much more clear when you have a getter message/method, rather than a property that is read-only and the only way to learn it is through the hard way.
    As for the "int v = d.GetFaceValue();" portion - you could do it, but now your Die class behavior is less predictable, since you have to assume that is does or does not commit something. This is the core of the principle. Hopefully my answer helps you.

  • Interesting. I've been using the GOF Command pattern for a while and this is the first I had heard of this as principle. It makes total sense. I just recently built an implementation of an Object Prevalence engine that uses exactly this pattern / principle. It's great because the framework can assume reader locks in the queries and reader/writer locks in the commands for maximum concurrency.

Comments have been disabled for this content.