Cohesion Demystified

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.

Code Examples of Cohesion (simplified)

To view or add a comment, sign in

More articles by Achilles M.

  • Design Patterns - Basic Iterator

    Among the most common things in a collection of items is the ability to iterate through the collection , in Java for…

  • Coupling

    In a nutshell coupling is about how strongly dependent are software modules to each other. In this article we will talk…

    6 Comments
  • Testable Code 101

    Testability is all about making our code (and our system eventually) to be easy to test. Why? Testable code is an…

    2 Comments
  • Design Patterns - Composite

    The composite design pattern is about a hierarchy where nodes with children have different behavior than childless…

  • Software Requirements 101

    The requirements should: Define what the system is doing but Not how is done! Functional : The Functional Requirements…

  • Design Patterns - Observer

    The observer design pattern is useful in cases we want a change in an object (subject) to be known to one or more other…

  • Typescript boilerplate

    A simple boilerplate for Typescript projects with Mocha, Chai and coverage report using nyc View project on GitHub Why…

  • Create a simple image picker for Android

    In this simple tutorial you will learn how to create an image picker for android ! Creating an image picker for your…

  • Boosting performance using an SSD

    What is this about While it's no big news you can use an SSD to boost the performance of any system , by usually…

  • Configure Vlan Maps on a Cisco Switch

    Vlan Maps are used to filter or redirect traffic in a Vlan , giving you more granular control over the traffic . Steps…

Explore content categories