DDDD: Why I Love CQRS

[UPDATE: This post was written about the time Greg Young formally named his CQS architectural implementation of command query separation.  Because of the change in terminology this post was written with the understanding that CQRS consisted of all elements commonly associated with CQRS.  In other words, CQRS herein is incorrectly defined as the following concepts together: DDD, event sourcing, domain events, true “CQRS”, and eventual consistency.  It should be noted that all of those concepts better fit under the umbrella of “DDDD” or Distributed Domain-Driven Design.  In Greg Young’s recent blog posts he clarifies what CQRS is and is not.]

There are a number of significant advantages to using an emerging pattern known as Command Query Responsibility Segregation (CQRS), formally known as Command Query Separation [Young].

vs. ActiveRecord

ActiveRecord is an incredibly quick and powerful way to create an application to deliver business value as evidenced by the abrupt emergence and fast-growing popularity of Ruby on Rails. Specifically, its power revolves around displaying and mutating objects matching a database schema, thus avoiding such technical complexity as the impedance mismatch problem.

A critical deficiency to ActiveRecord is when business logic reaches a certain level of complexity. Once at that point, ActiveRecord begins to “break down” and it becomes difficult to ensure that all business logic is properly maintained in a single location and handled in a consistent fashion.

Furthermore, all business state is governed by the database. In other words, the database becomes the single point of failure and performance bottleneck. Possible resolutions might include sharding the database but referential integrity and distributed transactions could become an issue. These could be abandoned but that would require more technical complexity to ensure consistent application state. Further, reconstructing a report or screen would then require retrieval of data from disparate sources.

vs. Traditional Domain Model

Domain-Driven Design should be used when business complexity merits the overhead and difficulty of discovering the correct domain model. Otherwise, ActiveRecord or another type of pattern should be used. Even so, DDD has the advantage of isolating all business logic into a single location. Even with "anemic" domain models the logic is still in one place.

A significant downside of traditional DDD is found in the common practice of using an object-relational mapper or similar data access strategy. Specifically, the domain objects may not necessarily be truly “POCO” or “POJO”. For example, in C# you end up having to declare your methods as “virtual” or you may have to create unused, protected constructors. Some ORMs even require you to use a certain base class in order for the ORM to perform its magic.

In addition, many DDDers query their domain objects through a repository for data to display on a report or screen. Many also have their domain objects return a DTO that can be databound to the screen. The problem here is that domain objects are not meant for display—they’re behavioral entities–they have behavior rather than shape. This often results in additional properties on domain model entities to support information needed on a particular report or screen. Lastly, because the domain object is now used for display, there is an extra level of coupling that must be addressed when refactoring domain objects.

CQRS: A Class By Itself

The CQRS style of programming isolates domain complexity into a particular location like its traditional DDD counterpart, but it doesn’t expose state—only behavior through methods that can be invoked and that return "void". In this way, the domain model is strictly behavioral and can more easily be refactored towards deeper insight.

There are a number of significant, positive consequences when using CQRS that you don’t get by default with the aforementioned patterns.

  1. Distributed systems capabilities: CQRS facilitates spreading your application across multiple physical machines using messaging patterns.
  2. High availability: Because the application is distributed, each piece can continue to function in the absence or failure of any other piece. Further, the distributed nature has a “load leveling” effect whereby spikes in demand are leveled using messaging.
  3. External systems integration: Messaging patterns  facilitate the ability to easily replicate both the intent as well as the data of domain events to external systems.
  4. NoSQL: CQRS doesn’t even require a database to support the domain model. It only needs a relational database if you choose to use one for reporting. This prevents the reporting database from being a single point of failure or even a bottleneck because it can be scaled independently from the rest of the application.
  5. Auditing and historical tracing: I’ve done a lot of work with temporal databases in an attempt to have a complete and accurate audit. (That’s what attracted me to this pattern in the first place.) The problem with temporal DBs and schemas is that the technical complexity quickly overwhelms the business complexity as the two become easily mixed. In CQRS, we capture each state transition explicitly which gives us a complete and accurate historical record that we can fast forward or rewind to any point in time.
  6. One repository: There has been some debate over the last few months about the viability of the repository pattern. The argument is that a repository cannot handle all of the querying needs of the application. This is absolutely, 100% correct, which is why we should only use the repository in the domain model to query by ID in order to get a single domain object back. When we need data for a particular screen or report we should use the correct tool for the job and go straight to the database. This is what databases are designed for and CQRS appropriately pushes us in that direction.
  7. Screen-based reporting: Rather than trying to bind domain objects to the screen, CQRS tells us to query the database directly and to have simple DTOs which are screen-based objects. This allows us to query all the information necessary for a particular screen in a single request rather than 3, 4, 5, or even 15 DB requests per screen. This also makes development using MVC patterns significantly easier.

Conclusion

While reading technical blog posts or listening to technical podcasts, I am constantly amazed at how elegantly and beautifully CQRS solves a multitude of deficiencies found in more established or “more traditional” approaches.

  • Anonymous

    Hello,

    I do not have any programming experience with this, but I watched often Youngs presentations and I am reading his blog. I like this approach.

    But I would like to see a good article about DDDD, not only posts.

    regards

  • http://blog.fohjin.com Mark Nijhof

    Great read! Perhaps you are interested in an example I created of CQRS after having spend to much time with Greg discussing it?

    Link: http://github.com/MarkNijhof/Fohjin

    -Mark

  • http://www.blogger.com/profile/16836313591238262040 Jonathan Oliver

    Mark,

    I have been pouring over your sample application ever since it was released. I may have a few more small patches that would help smooth some areas that currently use reflection.

  • http://www.redmelon.net Douglas

    Do you know of anyone implementing a temporal database as described in the article backed by MS SQL?

  • http://www.blogger.com/profile/16836313591238262040 Jonathan Oliver

    I don't know why you would want to subject yourself to so much pain and complexity. In any event, you can find a free PDF book by Richard Snodgrass online which explains how to implement a temporal DB on top of a traditional relational DB such as SQL Server.

  • http://www.blogger.com/profile/09089938342974440835 ImaginaryDevelopment

    can you provide some links to some good CQRS references you would recommend?

  • http://www.blogger.com/profile/16836313591238262040 Jonathan Oliver

    @ImaginaryDevelopment: Take a look at this:
    http://blog.jonathanoliver.com/2009/03/dddd-and-cqs-getting-started.html

    Also, I noticed your blog focused on re-usability and I thought you might find this to be a good read:
    http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/

  • http://www.blogger.com/profile/09089938342974440835 ImaginaryDevelopment

    I have read it, it's a nice article and I have certainly hit some of those pitfalls.

    "Get into a rut early: Do the same process the same way. Accumulate idioms. Standardize. The only difference(!) between Shakespeare and you was the size of his idiom list – not the size of his vocabulary. " – EPIGRAMS IN PROGRAMMING – http://www.cs.yale.edu/quotes.html I read that as acquire a bag of reusable tricks. Without practicing reuse and learning how to sculpt good reusable code, I don't think we'd have the .net framework. So despite many failures I've had some successes in truly useful reusable code.

  • http://www.blogger.com/profile/14168696990355931491 pub-2190557680964036

    JdonFramework is a CQRS framework in Java, it has domain events, and batch query supports: jdon.dev.java.net

  • http://simon-says-architecture.com/ Szymon Pobiega

    What I really like in CQRS/DDD is the testability (compared to traditional DDD with ORM). Clear separation of behavior (a method) and a state change (an event and its handler) make my tests cleaner.

    For example, I want to check how Order object behaves when I add fifth line item to it. In traditional DDD, I would have 4 AddLine calls in 'arrange' phase of the test and finally one call in the 'act'.

    With CQRS, I only need to apply 4 LineAdded events in 'arrange' phase. I do not call any business logic so I am sure my 'arrange' phase is safe (chances of failure are marginal). In original solution, I was testing not only how AddOrder behavers when called fifth time, but also how it behaves the first 4 times.

  • Pingback: Kool Architectural Resources and Sample Apps(mostly in .NET) « Insight's Delight