664

What is the difference between cohesion and coupling?

How can coupling and cohesion lead to either good or poor software design?

What are some examples that outline the difference between the two, and their impact on overall code quality?

Mustafa Kemal
  • 762
  • 1
  • 5
  • 11
JavaUser
  • 25,542
  • 46
  • 113
  • 139
  • 3
    check it out: http://msdn.microsoft.com/en-us/magazine/cc947917.aspx – Inv3r53 Jun 21 '10 at 14:03
  • 6
    I would like to point out to this article: [S.O.L.I.D. Software Development, One Step at a Time](http://www.code-magazine.com/article.aspx?quickid=1001061&page=1). Grz, Kris. – Kris van der Mast Jun 21 '10 at 14:40
  • 5
    [This](http://enterprisecraftsmanship.com/2015/09/02/cohesion-coupling-difference/) is latest post on this subject – janisz Sep 02 '15 at 12:22
  • 4
    See also: http://stackoverflow.com/questions/39946/coupling-and-cohesion – davidpricedev Sep 08 '15 at 14:04
  • 1
    In fact, this is a duplicate of that one. – cellepo Jul 06 '20 at 19:56
  • I've come back to this page over the past few years and often rediscover how subjective these answers are. IMHO, that's because the words are being used subjectively. When we like the combination of 2 things, we say **"good cohesion"**, and when they're bad, we say **"tight coupling"**. Removal of good/tight is pretty confusing - but **TLDR:** the more different something is, the further it should be away. Apparently this doesn't work too well for teams though - this is the opposite of diversity . – Ben Butterworth Aug 03 '22 at 12:46

16 Answers16

938

Cohesion refers to what the class (or module) can do. Low cohesion would mean that the class does a great variety of actions - it is broad, unfocused on what it should do. High cohesion means that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.

Example of Low Cohesion:

-------------------
| Staff           |
-------------------
| checkEmail()    |
| sendEmail()     |
| emailValidate() |
| PrintLetter()   |
-------------------

Example of High Cohesion:

----------------------------
| Staff                   |
----------------------------
| -salary                 |
| -emailAddr              |
----------------------------
| setSalary(newSalary)    |
| getSalary()             |
| setEmailAddr(newEmail)  |
| getEmailAddr()          |
----------------------------

As for coupling, it refers to how related or dependent two classes/modules are toward each other. For low coupled classes, changing something major in one class should not affect the other. High coupling would make it difficult to change and maintain your code; since classes are closely knit together, making a change could require an entire system revamp.

Good software design has high cohesion and low coupling.

Connor Low
  • 5,900
  • 3
  • 31
  • 52
mauris
  • 42,982
  • 15
  • 99
  • 131
  • 23
    I don't see how removing a few methods, and adding a few others increases cohesion. Can someone help here please? – Saket Jain Jan 27 '16 at 09:44
  • 15
    @SaketJain it's not just removing some methods and adding some others. it's how the methods are related to the purpose of the class (if that explanation is clearer). – mauris Jan 27 '16 at 09:46
  • @mauris I understand that. But it wasn't clear (at least to me), how the methods are now increasing cohesion. Could you perhaps list where the other methods might go? – Saket Jain Jan 27 '16 at 09:59
  • 6
    the example of low cohesion at the top looks pretty good, I think you accidentally meant to say "high cohession" – relipse Mar 04 '16 at 14:45
  • 66
    @SaketJain The Staff class it's not the place where we check, send or validate emails. Those functions should go inside an hypothetical Email class, that's the reason it's a low cohesion. In the second example the Staff class contains only proper information for setting and getting Staff related data. They don't perform actions that should be managed by another class. – Antonio Pantano Oct 14 '16 at 22:09
  • The two examples of cohesion doesnt prove the difference. Consider a new more helpful example. The fact that you remove print is ok, but what has get set functions to do with it? – JonathanC Feb 15 '19 at 06:23
  • How is it different from `Single Responsibility Principle` – Mehraj Malik Nov 07 '19 at 06:05
  • 4
    @MehrajMalik, they relatable. But I think the `Single Responsibility Principle` is one of the causes of `High Cohesion & Low Coupling` (the consequence). Thinking deeply about each responsibility, you gain independent components in your system and better communication between them. – imtk Dec 08 '19 at 13:32
  • 3
    @JonathanC the examples don't need to prove the difference (like in a math proof) to still be an example. Feel free to Answer or Comment any examples you feel are more helpful. The `set` & `get` functions illustrate functionality that is more specific to the "Staff" context - the higher specificity give that example its higher cohesion. – cellepo Dec 20 '19 at 02:28
  • 2
    Great answer! I have had to answer this question in three software engineer interviews already. – Luke Damkoehler Aug 05 '22 at 20:43
99

High cohesion within modules and low coupling between modules are often regarded as related to high quality in OO programming languages.

For example, the code inside each Java class must have high internal cohesion, but be as loosely coupled as possible to the code in other Java classes.

Chapter 3 of Meyer's Object-Oriented Software Construction (2nd edition) is a great description of these issues.

Christophe
  • 68,716
  • 7
  • 72
  • 138
CesarGon
  • 15,099
  • 6
  • 57
  • 85
  • 5
    The concepts aren't really limited to OO programming. If anything, I would suggest that a goal of OO languages is to guide the programmer towards the objectives of high cohesion/low coupling. – Hutch Feb 15 '19 at 23:53
  • Bertrand Meyer was so kind to publish his book online and free of charge on his web site (link updated) – Christophe Dec 17 '22 at 15:48
94

Cohesion is an indication of how related and focused the responsibilities of an software element are.

Coupling refers to how strongly a software element is connected to other elements.

The software element could be class, package, component, subsystem or a system. And while designing the systems it is recommended to have software elements that have High cohesion and support Low coupling.

Low cohesion results in monolithic classes that are difficult to maintain, understand and reduces re-usablity. Similarly High Coupling results in classes that are tightly coupled and changes tend not be non-local, difficult to change and reduces the reuse.

We can take a hypothetical scenario where we are designing an typical monitor-able ConnectionPool with the following requirements. Note that, it might look too much for a simple class like ConnectionPool but the basic intent is just to demonstrate low coupling and high cohesion with some simple example and I think should help.

  1. support getting a connection
  2. release a connection
  3. get stats about connection vs usage count
  4. get stats about connection vs time
  5. Store the connection retrieval and release information to a database for reporting later.

With low cohesion we could design a ConnectionPool class by forcefully stuffing all this functionality/responsibilities into a single class as below. We can see that this single class is responsible for connection management, interacting with database as well maintaining connection stats.

Low Cohesion Connection Pool

With high cohesion we can assign these responsibility across the classes and make it more maintainable and reusable.

High Cohesion Connection Pool

To demonstrate Low coupling we will continue with the high cohesion ConnectionPool diagram above. If we look at the above diagram although it supports high cohesion, the ConnectionPool is tightly coupled with ConnectionStatistics class and PersistentStore it interacts with them directly. Instead to reduce the coupling we could introduce a ConnectionListener interface and let these two classes implement the interface and let them register with ConnectionPool class. And the ConnectionPool will iterate through these listeners and notify them of connection get and release events and allows less coupling.

Low Coupling ConnectionPool

Note/Word or Caution: For this simple scenario it may look like an overkill but if we imagine a real-time scenario where our application needs to interact with multiple third party services to complete a transaction: Directly coupling our code with the third party services would mean that any changes in the third party service could result in changes to our code at multiple places, instead we could have Facade that interacts with these multiple services internally and any changes to the services become local to the Facade and enforce low coupling with the third party services.

  • 4
    Excellent answer! If possible, could you use some other example? Connection Pooling might not be clear to everyone. Regardless, it really helped me. So thanks! – Saket Jain Jan 27 '16 at 09:56
  • how does using the ConnectionListener Interface help in reducing coupling?Can you provide an example that is easier to understand. – abhishek gupta Apr 30 '16 at 19:12
  • 2
    @abhishekgupta In this example you might have noticed that we have used observer pattern to achieve low/loose coupling. Going through this would help [How does Observer create loosely-coupled design?](http://programmers.stackexchange.com/questions/234230/how-does-observer-create-loosely-coupled-design) – Madhusudana Reddy Sunnapu May 01 '16 at 04:36
59

simply, Cohesion represents the degree to which a part of a code base forms a logically single, atomic unit. Coupling, on the other hand, represents the degree to which a single unit is dependent on others. In other words, it is the number of connections between two or more units. The fewer the number, the lower the coupling.

In essence, high cohesion means keeping parts of a code base that are related to each other in a single place. Low coupling, at the same time, is about separating unrelated parts of the code base as much as possible.

Types of code from a cohesion and coupling perspective:

Ideal is the code that follows the guideline. It is loosely coupled and highly cohesive. We can illustrate such code with this picture: enter image description here

God Object is a result of introducing high cohesion and high coupling. It is an anti-pattern and basically stands for a single piece of code that does all the work at once: enter image description here poorly selected takes place when the boundaries between different classes or modules are selected poorlyenter image description here

Destructive decoupling is the most interesting one. It sometimes occurs when a programmer tries to decouple a code base so much that the code completely loses its focus:enter image description here

read more here

Magne
  • 16,401
  • 10
  • 68
  • 88
Alireza Rahmani Khalili
  • 2,727
  • 2
  • 32
  • 33
  • 1
    Excellent article and the illustrations! If I may suggest an improvement to just one thought, I like how the 'poorly selected' keeps the groups of components with unrelated semantics in little swarms, but I think they should have visibly more arrows between them. After all, even on your 4-squares graphs this is the one that falls into the upper range of the 'Coupling' axis. – Slawomir Brzezinski Jul 07 '19 at 19:21
  • 1
    I would also say that 'poorly selected' should have less arrows inside each swarm. Using the 'folder structure' example from your article, which you categorize as 'poorly selected' repositories or factories will certainly not talk to each other. – Slawomir Brzezinski Jul 07 '19 at 19:29
  • UPDATE: I raised these suggestions to the original author of the image [and the author agreed with them](https://enterprisecraftsmanship.com/2015/09/02/cohesion-coupling-difference/#comment-4534792523). – Slawomir Brzezinski Jul 13 '19 at 10:12
  • 1
    That was a great answer, simply explained. I find one of the most common forms of "poorly selected" is what you might call "cohesion by type". You see this all over the place, for example a package structure that contains "screens", and all the screens are in there, and another called "dialogs" and all the dialogs are in that package. The result is that you get MyABDialog in one place, and MyABScreen in another place. Organizing that way actually breaks cohesion, and introduces coupling where it didn't need to exist, while *looking like* you are a applying good pattern. – Brill Pappin Jan 12 '22 at 18:39
34

best explanation of Cohesion comes from Uncle Bob's Clean Code:

Classes should have a small number of instance variables. Each of the methods of a class should manipulate one or more of those variables. In general the more variables a method manipulates the more cohesive that method is to its class. A class in which each variable is used by each method is maximally cohesive.

In general it is neither advisable nor possible to create such maximally cohesive classes; on the other hand, we would like cohesion to be high. When cohesion is high, it means that the methods and variables of the class are co-dependent and hang together as a logical whole.

The strategy of keeping functions small and keeping parameter lists short can sometimes lead to a proliferation of instance variables that are used by a subset of methods. When this happens, it almost always means that there is at least one other class trying to get out of the larger class. You should try to separate the variables and methods into two or more classes such that the new classes are more cohesive.

Cătălin Rădoi
  • 1,804
  • 23
  • 43
  • 2
    I agree this is probably the best explanation, this is what I like in Uncle Bob, that he can explain the actual meaning in a few phrases. Knowing this definition you can instantly see what should be done to given class to increase its cohesion. – Pawel Dubiel Mar 15 '20 at 09:52
  • This is a good explanation in the specific context of object-oriented design, but these concepts apply more generally. Other responses and (blog references) here provide good explanations in the more general context. – Eric Zoerner Dec 24 '20 at 15:41
34

Increased cohesion and decreased coupling do lead to good software design.

Cohesion partitions your functionality so that it is concise and closest to the data relevant to it, whilst decoupling ensures that the functional implementation is isolated from the rest of the system.

Decoupling allows you to change the implementation without affecting other parts of your software.

Cohesion ensures that the implementation more specific to functionality and at the same time easier to maintain.

The most effective method of decreasing coupling and increasing cohesion is design by interface.

That is major functional objects should only 'know' each other through the interface(s) that they implement. The implementation of an interface introduces cohesion as a natural consequence.

Whilst not realistic in some senarios it should be a design goal to work by.

Example (very sketchy):

public interface IStackoverFlowQuestion
      void SetAnswered(IUserProfile user);
      void VoteUp(IUserProfile user);
      void VoteDown(IUserProfile user);
}

public class NormalQuestion implements IStackoverflowQuestion {
      protected Integer vote_ = new Integer(0);
      protected IUserProfile user_ = null;
      protected IUserProfile answered_ = null;

      public void VoteUp(IUserProfile user) {
           vote_++;
           // code to ... add to user profile
      }

      public void VoteDown(IUserProfile user) {
          decrement and update profile
      }

      public SetAnswered(IUserProfile answer) {
           answered_ = answer
           // update u
      }
}

public class CommunityWikiQuestion implements IStackoverflowQuestion {
     public void VoteUp(IUserProfile user) { // do not update profile }
     public void VoteDown(IUserProfile user) { // do not update profile }
     public void SetAnswered(IUserProfile user) { // do not update profile }
}

Somewhere else in your codebase, you could have a module that processes questions regardless of what they are:

public class OtherModuleProcessor {
    public void Process(List<IStackoverflowQuestion> questions) {
       ... process each question.
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Adrian Regan
  • 2,240
  • 13
  • 11
16

Cohesion in software engineering is the degree to which the elements of a certain module belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.

Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.

I wrote a blog post about this, if you want to read up in a little bit more details with examples and drawings. I think it answers most of your questions.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
13

enter image description here

cohesion refers all about how a single class is designed. Cohesion is the Object Oriented principle most closely associated with making sure that a class is designed with a single, well-focused purpose. The more focused a class is, the cohesiveness of that class is more. The advantages of high cohesion is that such classes are much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes.

In the above image, we can see that in low cohesion only one class is responsible to execute lots of job which are not in common which reduces the chance of re-usability and maintenance. But in high cohesion there is a separate class for all the jobs to execute a specific job, which result better usability and maintenance.

vkstream
  • 881
  • 8
  • 8
3

Cohesion (Co-hesion) : Co which means together, hesion which means to stick. The System of sticking together of particles of different substances.

For real-life example:
enter image description here
img Courtesy

Whole is Greater than the Sum of the Parts -Aristotle.

  • Cohesion is an ordinal type of measurement and is usually described as “high cohesion” or “low cohesion”. Modules with high cohesion tend to be preferable, because high cohesion is associated with several desirable traits of software including robustness, reliability, reusability, and understandability. In contrast, low cohesion is associated with undesirable traits such as being difficult to maintain, test, reuse, or even understand. wiki

  • Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa. Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability. wiki

Premraj
  • 72,055
  • 26
  • 237
  • 180
2

I think the differences can be put as the following:

  • Cohesion represents the degree to which a part of a code base forms a logically single, atomic unit.
  • Coupling represents the degree to which a single unit is independent from others.
  • It’s impossible to archive full decoupling without damaging cohesion, and vice versa.

In this blog post I write about it in more detail.

Vladimir
  • 1,630
  • 2
  • 18
  • 28
2

Cohesion is an indication of the relative functional strength of a module.

  • A cohesive module performs a single task, requiring little interaction with other components in other parts of a program. Stated simply, a cohesive module should (ideally) do just one thing.
  • Conventional view:

    the “single-mindedness” of a module

  • OO view:

    cohesion implies that a component or class encapsulates only attributes and operations that are closely related to one another and to the class or component itself

  • Levels of cohesion

    Functional

    Layer

    Communicational

    Sequential

    Procedural

    Temporal

    utility

Coupling is an indication of the relative interdependence among modules.

  • Coupling depends on the interface complexity between modules, the point at which entry or reference is made to a module, and what data pass across the interface.

  • Conventional View : The degree to which a component is connected to other components and to the external world

  • OO view: a qualitative measure of the degree to which classes are connected to one another

  • Level of coupling

    Content

    Common

    Control

    Stamp

    Data

    Routine call

    Type use

    Inclusion or import

    External #

z atef
  • 7,138
  • 3
  • 55
  • 50
2

The term cohesion is indeed a little counter intuitive for what it means in software design.

Cohesion common meaning is that something that sticks together well, is united, which are characterized by strong bond like molecular attraction. However in software design, it means striving for a class that ideally does only one thing, so multiple sub-modules are not even involved.

Perhaps we can think of it this way. A part has the most cohesion when it is the only part (does only one thing and can't be broken down further). This is what is desired in software design. Cohesion simply is another name for "single responsibility" or "separation of concerns".

The term coupling on the hand is quite intuitive which means when a module doesn't depend on too many other modules and those that it connects with can be easily replaced for example obeying liskov substitution principle .

zar
  • 11,361
  • 14
  • 96
  • 178
  • 1
    Why do people keep using the word module instead of class? – northerner Feb 06 '19 at 12:41
  • 2
    @northerner its just more generic term. – zar Feb 06 '19 at 15:43
  • Here's an article describing that cohesion and SRP are actually *not* the same thing. It further explains, that the only thing you actively do - in terms of maintaining a "high cohesion" - is not to tear things apart that belong together. This is *not* the same as SRP. https://stackoverflow.com/questions/11215141/is-high-cohesion-a-synonym-for-the-single-responsibility-principle – Alan Dec 01 '21 at 15:52
1

Coupling = interaction / relationship between two modules... Cohesion = interaction between two elements within a module.

A software is consisting of many modules. Module consists of elements. Consider a module is a program. A function within a program is a element.

At run time, output of a program is used as input for another program. This is called module to module interaction or process to process communication. This is also called as Coupling.

Within a single program, output of a function is passed to another function. This is called interaction of elements within a module. This is also called as Cohesion.

Example:

Coupling = communication in between 2 different families... Cohesion = communication in between father-mother-child within a family.

Dipankar Nalui
  • 1,121
  • 5
  • 18
  • 33
1

Simply put, cohesion means that a class should represent a single concept.

The public interface of a class is cohesive if all the class features are related to the concept that the class represents. For example, instead of having CashRegister class, having CashRegister and Coin features cohesion makes it into 2 classes - CashRegister and Coin class.

In coupling, one class depends on another as it uses the objects of the class.

The problem with high coupling is that it can create side effects. One change in one class could cause an unexpected error in the other class and could break the whole code.

Generally, high cohesion and low coupling is considered high quality OOP.

Pang
  • 9,564
  • 146
  • 81
  • 122
1

Theory Difference

Cohesion

  • Cohesion is an indication of relative functional strength of module.
  • A cohesive module performs a single task, requiring little interaction with other components in other parts of program.
  • A module having high cohesion and low coupling is said to be functionally independent of other module.

Classification of Cohesion

1.Coincidental 2.Logical 3.Temporal 4.Procedural 5.Communication 6.Sequential 7.Functional

Coupling

  • Coupling is indication of relative interdependence among modules.
  • Degree of coupling between two modules depends on their interface complexity.
0

In simple terms, Cohesion is "the code that changes together stays together". Coupling is "a change to one component requires change to another component".

Cohesion applies to the code that is within a boundary and coupling applies to the code across the boundary.

A system is stable if cohesion is strong and coupling is low. This is the mantra in microservice world.

Different types of coupling: (from loose to strong)

  • Domain Coupling - one microservice needs to interact (to use the functionality) with another microservice
  • Pass-through Coupling - One microservice passes data to another microservice purely to be used by another downstream service
  • Common Coupling - 2 microservices uses a common set of data (like a shared database or cache)
  • Content Coupling - Upstream service changes the internal state of the downstream service