Command Query Separation

Have a look at your current application for a moment and try to split it into two parts – the ‘read-only’ side and the write side. Please notice that I have mentioned the word ‘read-only’ side. As the name suggests, the read-only side is the side of the application that is responsible for reading data from the database and displaying it on the UI. No where during the request is it supposed to save any change back to the database. Displaying data in pagable, sortable grid falls under the ‘read-only’ side of the application. Reports would fall under ‘read-only’ side. These are the requests that do not make any change to the database. In other words, it do not change the state of system

Where-as, the other side of the application i.e the write-side of the application would persist changes made by the users into the database.

Let’s say that you were to architect the read-only and the write sides of the application separately, as though they were two different systems, what would some of the design goals that you would come up with? Try to do this exercise with your current application and put down few design goals in the order of their priorities for each side.

As far as I am concerned, eighty percent of my users are going to use twenty percent of my application. Moreover, this twenty percent of the application consists primarily of the read-only side of the application. Hence, for me, some of the high priority design goals for the read-only side of my applications would be

1. Performance
2. Scalability

By no means am I attempting to suggest that the write-side of the application is any less important. In my case, it is actually the foundation for the read-side and hence is critically important for the success of the system. But, it has different design priorities. Since, it mostly deals with complex business rules and ensures non-corruption of data, some of the design goals that would top the list would be as follows,

1. Data Integrity
2. Maintainability
2. Extendibility
3. Flexibility

Clearly, the architectural needs of the read-only and write sides of my application are different in nature. Is it the same for you also? If it is, then the question we should be asking ourselves is that does it justify applying or rather imposing same architectural patterns to both sides of application just for the sake of symmetry?

Rich object graphs are ideal for write-side of the application. They result in high degree maintainable code. But they start to play nasty in situations where complex joins are needed and high performance is a priority, something that the read-only side of application needs a lot. And really! These old fashioned stored procedures and inline queries works like charm in these kind of situation. But the problem with Stored Procedures and inline query approach is that they do not provide the same kind of maintainability and data integrity that rich object graphs do. Hence, separating out the read-only and the write sides of the application and applying different architectural patterns to both can very well be the answer.

Bertrand Meyer in his book “Object Oriented Software Construction” separates an object’s methods into two categories:

Queries: Return a result and do not change the observable state of the system (are free of side effects). In other words, the read-only methods.

Commands: Change the state of a system but do not return a value. The write methods.

Meyer calls this principle the Command Query Separation. This principle, applied at architectural level leads to a clear segregation of the commands (write operations) and the queries (read-only operation) and lends itself to the flexibility of applying different architectural patterns to the very different design needs of the Command and Query sides of the application.


2 thoughts on “Command Query Separation

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s