Computer Science Canada Command/Query Separation |
Author: | wtd [ Wed Jun 28, 2006 11:11 am ] | ||||||||
Post subject: | Command/Query Separation | ||||||||
What the heck is Command/Query Separation? I think that to answer that, we have to think about what it isn't. As databases are the centerpiece around which most programming takes place these days, let's consider a problem in that domain. You want to write a method in your class that queries a database and then returns the results to you. Assuming we know how to query the database, this is a fairly straightforward task. In a vaguely Java-ish example:
And that would seem all well and good, but let's think about it. Our method is really doing two things. It's executing a command, by executing an SQL query on the database. This is a side-effect of the method. It's also returning some value. Command/Query Separation says this is a bad thing. It makes it more difficult to comprehend the program. A simple symptom of this is naming. Do we give the method a verb name, because it causes a side-effect, or a noun name because it returns a value? Rather, we would have something like:
Of course, it looks a bit nicer when expressed in the language Bertrand Meyer created with this and other ideas in mind.
Ignoring the difference in the length of the loop, Meyer's Eiffel is better at this. By default, features like the the_results variable are read-only from outside the object, meaning that distinct getters do not have to be written. Additionally, Eiffel enforces CQS. If we had written query_database such that it returned a value, we would not have been able to call procedures which cause side-effects from within it. A common real example of using CQS is reading input. A sample:
Command/Query Separation is a powerful concept, and one worth investigating if you're working with an object-oriented language. |