The forgotten realm of Cohesion

For the history of cohesion go to A brief history of coupling and cohesion. Below, we will focus on the concept itself and its types.

Now it’s time to focus on the classes themselves and the elements they consist of. When do we know that a specific element fits into a certain class? Sometimes what we assume does, actually doesn’t necessarily do it to for our colleague. In such a case, cohesion comes to the rescue. In general, it’s a measure of how elements go together.

Regarding cohesion, there was a problem with what to call it to start with. At the beginning it was named “intramodular functional relatedness”, but this term was found to be a bit clumsy. Cohesion was also called “binding” or “functionality”. In his book Myers calls it “module strength”, which is also entirely accurate as it can tell us how tightly elements of a class are bonded in the context of the functionality they perform – to what extent they are related. Finally, the term “cohesion” was chosen by analogy to the cohesion of groups – a similar concept in sociology. 

Glenn Vanderburg wrote a post where he explained why in his opinion programmers have a problem with understanding the whole concept of cohesion. He argues that the name is not as  self-explanatory as is the case of coupling and it is not used so often in everyday life, either. Because of that, we can’t refer it to our daily situations. To better visualize the term, he proposes comparing it to other words with the same root. For example, “adhesion”, which describes stickiness. If something sticks to something else, it is a one-sided process, often aided by a third-party – glue in most cases. He also used an example of duct tape that doesn’t have to fit into anything as due to its stickiness it sticks to almost anything. On the other hand, cohesive elements match each other perfectly, and there is no need to use any glue between them.

The better our understanding of a designed problem is, the higher cohesion we can end up with. This is why it is absolutely vital to spend time on getting familiar with the problem itself and the business domain. Once we know it quite well, we should focus on grouping elements in a way that reflects the problem. Thanks to that, we maximize relationships between them.

Now let’s think what drives the grouping of elements into a specific class. To answer that, we should take a closer look at types of cohesion, starting with one with the lowest and ending up with the highest degree of it.  

Types of Cohesion

Coincidental Cohesion

The first criterion for assigning elements to a specific class could be an actual lack of any criteria. It means that elements are grouped totally randomly – a real free-for-all. Such classes are created coincidentally and not in the process of design.

If we were to give this type any number on the scale of cohesion, we would probably give it a zero as there is no cohesion here at all.

Classes with this type of cohesion are quite rare but if we find any, they are probably artifacts of bad modularization. Usually, they are created because we find some sequence of methods’ calls in a few different places in our application, and we decide to extract them to a single class. Extracting, as we know, is not a bad thing, but if single methods do totally different things and, worse still, if we do it without thinking about what those sequences do in each of the contexts, we probably should leave them as they are. Otherwise, we can end up with a class that we will have to modify when something changes in one of those contexts but not in others.

Coincidental cohesion – total randomness in grouping elements into a class.

Logical Cohesion

In logical cohesion, elements of a class are grouped because they solve problems from the same category. Logically there is something that they have in common even though they have different functionalities.

A good example here could be mathematical operations, as each of them can do various things, but often they are grouped in some Math or Utils class with… mathematical operations.

The above-mentioned Utils classes are usually good examples of this kind of cohesion. One to rule them all!

Logical cohesion – class’ elements solve the same type of problems. For example,  a class that aggregates all mathematical operations.

Temporal Cohesion

If logical cohesion is combined with another grouping criterion that is the moment of execution, we will probably get temporal cohesion.

The best examples of this type of cohesion would be classes/modules that initialize, stop, or clean something. Initialization methods are logically connected as they “initialize something”. What is more, those methods usually have to be executed at some specific point in time or period.

Quite often, such classes/modules need to have this type of cohesion, and any attempts to change it to more cohesive types are highly ineffective.

Temporal cohesion – elements of the class have to be executed within the same period.

Procedural Cohesion

The next type is procedural cohesion, and it usually occurs when instead of modelling a domain we focus on an algorithm of execution – the order of steps that have to be executed to get from state “A” to state “B”. It may lead us to the approach where we end up modelling the algorithm itself and not the problem that we were supposed to solve.

Cohesion in this type is higher as elements are not only grouped because of their moment of execution like in temporal cohesion, but they also have to be executed in a specific order.

Loops, multiple conditions, and steps in the code can show evidence of procedural cohesion. Those are usually classes that, while being analysed, make us want to take a piece of paper, a pencil and start to draw a block diagram. 

Procedural cohesion – usually when we model algorithm itself and not the problem that we were supposed to solve

Communicational Cohesion

The first type of cohesion that focuses on the modelled problem is communicational cohesion. The criterion for grouping elements into a class here is that they are communicationally connected, which means that they work on the same input or return the same type of output data. Thanks to that, it can be easier to reuse the whole class in different contexts.

Classes like this have origins in thinking about operations that can be done on some particular set of data, or on the other hand – operations that have to be executed to get that set of data.

Communicational cohesion – elements in the class are grouped because they are communicationally connected, so they use the same input data or return the same output data.

Sequential Cohesion

At the stage when we group elements because of their sequence of data processing, so that the output of one element is at the same time input of the next one we probably have a brush with sequential cohesion.

There could be only one small issue here. If we have such a sequence, we can cut it in different ways. It means that created classes can do more than one functionality, or quite the opposite – only some part of the functionality. That’s the only reason why in the hierarchy of cohesion types it stands below the last one, which is functional cohesion.

Sequential cohesion – we group elements because of the sequence of data processed by them.

Functional Cohesion

We achieve it when all elements within a class are there because they work together in the best possible way to accomplish the goal – functionality. Each processing element of such a class is its integral part and is critical for the functionality of the class. The class itself performs no less and no more than one functionality.

What’s interesting, mathematical operations are often mentioned as an example of functional cohesion because they do exactly what they should and nothing more than that. I have also mentioned mathematical operations in logical cohesion, but there all operations were grouped in a Utils or Math class, and now I mean more creating a class per operation. So the responsibility of a single class would be only to perform a single operation.

It can be quite easy to judge whether a class has functional cohesion when we deal with a “small” functionality, but at higher levels of abstractions it can become a bit tricky. That’s why we can try to do it by looking for signs of other types of cohesion – similar to the case of data coupling. A bit like a shell game. For that, chapter “Exercises” could be helpful. You will find there quite interesting high-level exercises that can help you with everyday work to define what type of cohesion your class has, so don’t stop, keep reading :).

Functional cohesion – elements within a class are there because they work together in the best possible way to accomplish the goal – functionality.

Nonlinearity

When it comes to types of cohesion, one more thing is worth mentioning. In the book Reliable Software Through Composite Design as well as in Structured Design, the authors suggested assigning a weight to each of those types. Nevertheless, what is most important here they were quite reticent about it. That’s because they insisted that it might be a bit too early for it and they didn’t want it to influence future research into cohesion. They emphasized that values were chosen “based on educated guesses” and “these aspects of the model must be verified and refined based on data collected”.

The only reason why they decided to assign those weights, was to show that in their opinion those weights have nonlinear values and for example, in Structured Design, they were proposed as follows:

0: coincidental

1: logical

3: temporal

5: procedural

7: communicational

9: sequential

10: functional

When we can identify what types of cohesion our classes have, and we can see some places for improvements, these weights can be helpful as they can show us where we should utilize our energy. If we, for example, see that some class has sequential cohesion, it means that it is already almost “ideal” and maybe it makes no sense trying to get to functional cohesion. Instead, it is better to take care of places where the gain is higher, for example, between temporal and procedural cohesion.

Finally, some food for thought

Imagine a situation when without going into any details your colleague tells you “that new class that you’ve just created has poor cohesion.” I can imagine how adrenaline hits you, and at this stage, you probably can react in very different ways. You can flee, fight, or… debate.

Assuming that he or she is not a wild animal, and we are not going to end up as his or her dinner, I encourage you to take the third option. Maybe such a situation is just an opportunity to discuss and define what we understand as cohesion. Maybe we have a different understanding from our colleague. Next, we can also discuss what types of the term we can identify in our system and whether we allow them there or not. It’s not like some of them are right or wrong by default and we should avoid thinking in this way.

If you feel like some “stretching exercises” concerning cohesion, go to Stretch out for your cohesion.

P.S. If you have enjoyed this article and would like to always have it with you offline or you would like to have some super sketch notes with types of coupling and cohesion to print out and stick them above your bed, don’t hesitate and download an ebook, that I have for you. You will find there a few great posts about rotting design, coupling and cohesion put together into PDF, EPUB and MOBI formats.

* indicates required