Cohesion Demystified
Cohesion is about how focused a given program element is in performing a single cohesive task.
Cohesion is often contrasted with Coupling which is a different concept, but loose coupling correlates with high cohesion and vice versa. So by increasing the cohesion of our code it becomes less coupled and we avoid the pitfalls associated with coupling.
Cohesion is an ordinal measuring type that is usually described as "high cohesion" and "low cohesion".
High Cohesion
- Well focused code in performing a single task.
- Code with high cohesion is exhibiting: robustness, reliability, re-usability, and understand-ability.
Low Cohesion
- As the cohesion lowers , this code becomes more coupled and harder to maintain.
- Code with low cohesion has the undesirable traits of : being difficult to modify, test, reuse, and even to understand.
Reasoning about Cohesion
We start by asking questions like :
- "How tightly focused are the methods and fields in a Class ?"
- "Do all the elements of the Class work together to achieve a single Cohesive task?"
If a method does not use any field in its Class that is a red flag that this method is not cohesive with the Class and should be moved somewhere else.
Cohesion is really about how well the elements in the given Class really belong together.
Reasoning about cohesion can help the developer to better understand what tasks a given Class is doing and can use this information to group elements that belong together to new or other Classes that better suit the tasks we try to accomplish.
This process naturally leads to better organizing our code and make it easier to understand, modify and extend in the future.
Types of Cohesion
- Functional
- Sequential
- Communicational
- Procedural
- Temporal
- Logical
- Coincidental
The list starts with the highest Cohesive type : Functional to the lowest Cohesive : Coincidental.
Functional
The most Cohesive type of code where all code contributes to achieve a single well defined task.
Sequential
The output in a step is used as input to the next one.
An example would be executing a method that returns a result and using it to another method as input.
Communicational / Informational
The tasks are grouped only because they operate on the same data.
An example would be a method that operates differently on a string depending on it's value.
Procedural
Execution sequence is driven by control flow and follows a specific order, note that by changing the order can cause the code to not work as intended or even crash.
Temporal
Execution timing is the reason that given functionality is grouped together.
An example is the functionality called at a particular time in program execution: we call a function after we throw an exception to handle the exceptional behavior.
Logical
Functionality combined by performing a given task regardless of intent.
An example would be to group the input handling routines for keyboard, mouse and touch screen.
Coincidental
The total absence of Cohesion.
Functionality is arbitrarily grouped together, usually this happens to Classes with generic names like Utils.
The goal
Our designs should have high Cohesion and loose Coupling
The abstractions and our design should allow related elements (methods, fields) to be grouped together.