If you’ve ever wondered what Query/Command Separation means

Ok, the Distributed DDD guys are repurposing Query Command Separation to mean something more specific as an architectural pattern, but at the method level it just means that a method should either clearly change the state of the system or return values, but not both.  The point being to remove “surprises” from the code and hidden side effects.  Via the DailyWTF, here’s a beautiful example of violating CQS.  This isn’t to make fun of the subject of the WTF, but just to say that violating CQS in the code sample was a huge potential problem for the maintenance developers of that application.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://leibnizdream.wordpress.com Chance Coble

    It seems like you could use continuations in the above scenario.
    If your function that returns the identity just called on another function that takes the identity as an argument, you can keep the logic separate as well as pure.
    e.g. (pseudo C#)
    public A ProcessIdentity(Func prog)
    { return prog(LowLevelInsertCall()); }

    The flexibility and verifiability of this approach is one of the reasons monads are gaining momentum.

  • Hendry Luk

    I think there are certain cases where CQS *can* be violated, e.g.:
    - Fluent interface
    - Cached query. It’s a query, but it also changes its internal states to cache the result
    - CRUD (sans R), returns identity or number of affected rows
    - Efficiency in any bool Tryxxx() method. E.g. if we follow CQS and split login method into ‘authenticate’ (query) followed by ‘sign-in’ (command, which will call authentication query and throw exception if fails), authentication is done twice, instead of once with bool TryLogin().

    I think if applied brutally, CQS can actually cause more confussions, no?

  • Jim

    I’d say 99% of methods should follow CQS. The one exception is a method who’s return value is the byproduct of the state change… such as a method returning the identity value after a record insert.