Six Thoughts Before We Start 7
Think about your drill. I bet a well designed drill can be easily taken apart using the proper screwdriver.
The motor can be removed from the casing, the electrical system easily fixed or replaced, the drill bit holder
removed and repaired, and then the entire drill put back together again. This happens because the drill is both
loosely coupled together – each part is replaceable – and has high cohesion among its component parts.
Your code should be the same way: as was said above, it should be loosely but properly coupled. The modules
you build should be able to be composed together to form something useful, but in a way that makes the
system’s decomposition relatively easy. If you realize that a piece of your system is useful for another project,
you want to be able to easily reuse that module elsewhere without baggage from the current project. This is
what good coupling is about: easily fitting together modules that were not originally intended to do so.
As mentioned above, Legos show high cohesion. They can easily be pieced together to create almost anything
you can imagine. Even Duplo blocks have an interface to regular Legos that makes them very cohesive and
easy to combine. Legos can be taken apart very easily. They can be put together very easily. There is a reason
why they are the one of the most popular toys on the planet. Legos exhibit low coupling and high cohesion –
the main reason that they are so popular.
Your code should be like Lego blocks – easy to combine to create useful things.
Thoughts on Command Query Principle
In keeping with our previous discussion on encapsulation, let’s look at the notion of separating “commands”
and “queries” by using the Command/Query Principle. The notion was first discussed by Bertrand Meyer in
his book Object Oriented Software Construction¹⁰. This means that the idea is not new. In its basic form, it
means we should separate the things that read data from the system and the things that write data to the
system.
The Command/Query Principle states that there should be a clear separation between the updating of
information and status in your program and the way that you read information from it. Commands and
queries should be separately declared (though you’ll find that commands can call queries but not vice-versa).
It can be as complex as ensuring that reading and writing take place in completely separate classes, or as
simple as ensuring that commands and queries are put in different methods of your classes.
Of course, the first question you’ll have is “What do you mean by ‘command’ and ‘query’?” Well, I’ll tell you.
Queries
A query is an operation that returns a result without changing the state of the class or the application. In
Object Pascal, this is typically a function. As a general rule, queries should not change the state of a class. They
should be “idempotent,” meaning “denoting an element of a set that is unchanged in value when multiplied
or otherwise operated on by itself.” (I had to look that up, by the way….)
Queries should exhibit two main behaviors: they should return a single value and “asking a question should
not change the answer.” They should be referentially transparent, which means that they should be perfectly
replaceable with their literal result without changing the meaning of the system.
¹⁰http://www.amazon.com/gp/product/0136291554/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0136291554&linkCode=
as2&tag=nickhodgeshomepa&linkId=IVMYKYZ22AWZJ2LQ