Thursday, July 14, 2016

Cohesion



Today it is time for us to talk about more generic things on programming.

We say that a certain method has a good cohesion when it does one, and only one, thing.

I know... I know... this is too abstract! Let's see an example to make things clearer.

Consider the following piece of code

This will print all integers between 1 and 1000 whose sum of digits is 10. An easy task. I only separated it in two methods because we need this in order to better understand how important cohesion is.

If you take a look at these two methods, you'll notice the first one (some_method) invokes the other (sum_is_ten?) to ask if the sum of the digits of a certain value is ten. It passes only the value and receives only the information required. This is the perfect behavior, the perfect coupling between two methods. And this is only possible because sum_is_ten? has an excellent cohesion.  It does only one task, deciding if the sum of the digits in the numeric parameter received is ten or not.

Now let's consider another problem, a bit more complex. Now we need sum_is_ten? returning false when the parameter received is not multiple of four, even if the sum if the sum of the digits is ten. We could write it this way:

Or this way:


In this first way sum_is_ten? has a bad cohesion, 'cause it must decide for two things. But what are the consequences of this fact?

First of all, sum_is_ten? is less reusable. Imagine we had another method, say some_other_method, who also need to know if the sum of the digits of a certain number is ten, but not with this restriction about the number being multiple of four. It can't use sum_is_ten?, of course. In this situation we should write another method to perform this task and we wouldn't be able to avoid certain duplication of code.

Besides, the lack of cohesion makes the name of the method inconsistent.The name sum_is_ten? does not express clearly the goal of the method, as it is the ideal situation.

Of course this example is completely artificial, but it helps us to understand why cohesion is so important.

But there is still a point to be made clear: How to achieve a good cohesion?

Breaking things, is the answer! Separating different tasks in different methods and composing its results. In order to understand this, let's see the ideal  solution to our second problem, the list of all integers between 1 and 1000 whose sum of digits is equal to ten and who are also multiple of four.


As you may see, the ideal solution has a new method to decide if the given number is multiple of 4. This answer is composed with the the answer given by sum_is_ten?. Tasks are separated now, and each method executes one, and only one, task.

See you next post!