Back to Basics: Cohesion and Coupling Part 1
Cohesion and coupling are very misunderstood topics.
We have all heard that our code should be designed in such a way to increase cohesion and be loosely coupled. Is this correct? Is it even possible to achieve both?
Let's look a little at what cohesion and coupling are in order to better understand their relationship to our code.
Before you start learning up any new skill or concept, I suggest you take a look at my course “10 Steps to Learn Anything Quickly”.
What is cohesion?
Cohesion is simply quality of a thing being stuck together well.
We would say that something is highly cohesive if it has a clear boundary and all of it is contained in one place.
For example, a baseball is very cohesive. Everything that makes up a baseball is in one little round orb.
The internet is not cohesive. It is hard to define and it is scattered all over the place.
When looking at software, we consider a class or module to be highly cohesive if it has a clear responsibility and all of the implementation of that responsibility is close together or in one place.
A good example in software would be putting all of our logic to write to a database in one class or several classes in a module, instead of letting every part of our application that needs to write to the database implement that logic in its own class.
We consider cohesion to be a good thing because it makes software easier to understand, reduces the effects a change on one part of the system has on the rest of the system, and it allows us to reuse code within our application.
What is decoupling?
Decoupling is the quality of a thing not relying on other things.
We would say that something is decoupled if it does not depend on anything but itself. Something would be highly coupled if it had many different dependencies.
Consider an iPod. It is highly decoupled. It is a very self-contained piece of hardware. It has its own battery and can be transported around without depending on anything else for it to do its job.
Now consider the motherboard in your computer. It is not decoupled. It contains specific slots for RAM, for a CPU, for video cards, etc. If those components change in their shape or kind, they may not work with the motherboard.
Looking at software we can consider a module or class to be decoupled if it does not have many dependencies on other classes or modules.
Consider implementing a class for a linked list data structure. Chances are that class will be pretty decoupled, because it really shouldn’t depend on anything else. (Unless you of course change the granularity of what you consider a thing to be; more on that later.)
We like loosely coupled software because it reduces the impact of a change in one module across other modules. Loosely coupled software is also easier to reuse, because it doesn’t have many other dependencies to be included.
Sounds like they are trying to achieve very similar goals
And they are. For the most part high cohesion and loose coupling go together.
If your classes have clearly defined responsibilities with the implementation of those responsibilities located in that class, chances are it will be fairly decoupled from the rest of the system.
In the very general sense, as you decrease coupling, you increase cohesion and vice versa.
The benefits are very much the same also.
But now I’m going to get into some muddy water here and question what we mean by a “thing” or a “module.”
In my next post, I am going to delve much deeper into this topic and look at how granularity affects cohesion and coupling, as well as talk about how they can actually be inversely related.