Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

DDDD 10 [CQS]

 

Boring Sunday night so I figured I would get ahead on my posts for the week (I have not been good enough about hitting 5 but I am trying). This post is probably out of order but the concepts are simple, very important, and I will want to link to this later. Also this post and concept is valuable whether or not you are intending to use messaging.

 

At altdotnet one thing I talked a bunch about that most people had not really dealt with before was Command Query Separation( Martin Fowler also has a good post about it as well ). This is still a running theme in these posts; what I am talking about is rarely if ever new.

 

I know its a really big surprise that Greg is into things that are based in DbC … but later in our systems we will care *a lot* about what is mutating the state of the system and the consistency that is required for various actions.

 

Basically all things that change mutable state are commands and anything that only reads data is a query. Personally I like to add some further distinctions to this like “Only reads immutable state” vs “Reads mutable state” as with the latter I need to worry about the consistency of those reads but command and query are the roots.

 

To help think about Commands and Queries let’s look at them in terms of SQL as it has good separation (usually)

 

Command = Insert, Update, Delete
Query = Select (yeah surprisingly a query is a query :))

 

Not surprisingly commands and queries have quite different interactions in a SQL database (in fact most of what your transaction isolation levels (Read Commited, etc) talk about is how commands and queries interact with each other). This concept has largely been lost from our code and thought (largely because we rely on databases too much) though some have pushed greatly for this separation. Most systems allow too many things to become commands and queries at once leading to difficult to understand code… Patrick: this is a key metric 😉

 

This may seem quite weird to many people at first but one key point on commands vs queries is that commands should not return a value. Only a query is allowed to return a value though a command can technically change state that is passed into it so …

 

public void Foo(something s) {
    //modifies state 
    s.somevalue = “greg”;
}

 

is ok but ..

 

public string Foo() {
     //modifies state
     return “greg”;
}

 

is not!! this is a funny distinction eh?

 

In general I would prefer you in your code to follow an even TIGHTER distinction and assume that things passed into you are *also* immutable (The reason for this is that handling byref data in anything that crosses serialization boundaries is troublesome, but there are some cases where this can be ok (like setting something in a context)). It may feel really weird and unnatural at first but eventually it will become second nature; I promise. The only thing you are allowed to do is mutate state in some way (or add to an observable state hint hint).

 

We will get more into this later but as a critical thought what does this do to the concept of request/response? Maybe tomorrow?

 

 

Side Effect Free Functions and CQS

In Domain Driven Design, Eric Evans pushes Side Effect Free functions which are great and should be in your tool bag. What side effect free functions essentially do is change a command into a query. Instead of changing mutable state they create immutable state that is only visible to the caller. Since it is only visible to the caller it can be seen as a query as it is understood to be in a transient state and not visible to other queries.

This entry was posted in DDD, DDDD. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

3 Responses to DDDD 10 [CQS]

  1. Joe says:

    Would you consider a “Setter Method” (e.g. something like BlogPost.UpdateTitle(string newTitle) to be a command? If so, would you use an exception to indicate a validation error here rather than returning some kind of generic CommandResult instance?

  2. Greg,

    I’ve been enjoying your posts (I stayed late after work just to catch up reading all of them all today), as well as your discussions on the altdotnet mailing list, and have become quite interested in the idea of messaging. I’m sure to be enjoying your future posts as well!

    Just wanted to point out, for others like me going through these posts completely new to the idea of distributed applications, that Evan Hoff posted a link in the comments of DDDD4 that I’ve been reading through and has really been a great introduction. It’s an article by Pat Hellend, and I’ll reproduce the link here…

    http://msdn.microsoft.com/en-us/library/ms954587.aspx

    Keep up the good work!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>