Blog: Working with Large Codebases > Design Patterns & Architecture

Cohesion and Coupling in Large Projects


Tuesday, June 1st, 2010 - By Abhishek Rakshit

Cohesion and Coupling are commonly used metrics to gauge the design quality of a software project with regards to maintainability, reuse and understandability. These issues are commonly faced by developers working with large codebases. The mantra for these issues is to have a highly cohesive and loosely coupled codebase.

Simply stating, Cohesion means placing related code in one particular unit and Coupling is the degree of dependency between two or more units. If the code is highly coupled i.e. different units depend a lot on each other and modifying one feature can cause unwanted side effects. To avoid these the developer has to understand each of the related classes to update the behavior safely. Loosely coupled code is easier to reuse and on modification does not have undesired ripple effects in the code base. Adding to the benefits highly cohesive code promotes easy code understandability as everything is placed closely together. These aspects are not restricted to classes but apply to everything from methods in a class to packages in a project.

An interesting term I read a while ago was a class being termed internally as a ‘coupled blob’. The methods and properties in a class should agree with each other on what common behavior they all fall under vaguely justifying the term. A good OO developer strives to make the class reasonably close knit when it comes to the functionalities that a class is supposed to provide. If the class starts getting bigger and complicated it’s on the way towards becoming an external coupling hub and its probably a good time to start refactoring.

Although, it is unrealistic to expect everything related to a particular behavior in one unit, following some simple rules can help. Steps like providing intuitive names to methods and classes, moving closely related functionalities to a common class, or moving unrelated stuff out into appropriate classes, goes a long way towards helping to maintain a healthy code-base. Moreover, coupling in a project cannot be completely eliminated but needs to be controlled and a good start is to focus on de-coupling high-level components like packages. Controlling coupling at the coarse-grained level tends to eliminate a major part of the day-to-day issues we face. The Dependency Injection design pattern is also a good way to control coupling as it promotes having dependencies to an interface instead of concrete objects.

As with every coding practice misapplication of cohesion and coupling can create problems instead of solving them. Sometimes pushing cohesion too far can result in diminished returns when the cohesion strength rises to a point where it actually starts to hurt quality not improve it. This is often due to addition unnecessary code complications. Moreover pushing excessively towards a loosely coupled architecture can become a deterrent to optimizations and increase overhead due to added abstraction layers. In the end it is the developer who has to find the right balance between making the code-base more maintainable and understandable without adding performance issues to the application.

Note: Let us how you managed to strike the right balance with regards to cohesion and coupling to make your project better.

 

1 Tweet 5 Comments

5 Comments

  1. jamesbritt says:

    "[F]ollowing some simple rules can help. Steps like providing intuitive names to methods and classes, moving closely related functionalities to a common class, or moving unrelated stuff out into appropriate classes, goes a long way towards helping to maintain a healthy code-base"Well, you know, duh.

    A reason there are such problems with code is not that developers don’t quite know what they should be doing (though that is sometimes the case), but that many things that are easy to state in words are far from easy to do in practice.

    What, exactly, is "intuitive"? Intuitive to whom? How exactly do you decide when things are closely related? By what measure?

    This comment was originally posted on Hacker News

  2. abhirakshit says:

    Hey James I understand its not always easy to implement the best practices on real application and I have amply mentioned that in the post. What I am implying is that if we keep these things in mind and at least make an conscious effort to follow them it does really help.When I mean intuitive I mean something which will give a decent idea what that method or class is supposed to do. Also I am sure you must have some idea of how you can group code modules your project. Moreover looking at types of cohesion can give a decent idea of what elements can be grouped together.

    This comment was originally posted on Hacker News

  3. jamesbritt says:

    "When I mean intuitive I mean something which will give a decent idea what that method or class is supposed to do."OK, but that’s fraught with peril. You first have to know what the method or class is supposed to do now and in the future, and code has a tendency to mutate out from under you. The trouble is that the change can be slow and subtle, and then one day it strikes you (or, more likely, another developer) that the class has become kind of gnarly. The absence of fairly clear-cut guidelines means you’re winging it all along.

    "Also I am sure you must have some idea of how you can group code modules your project."

    Things go together until the don’t. Over time the behavior some code creeps over to some new realm, and one day you find the code a bit tangled. I’m wondering to what extent there are, or can be, applicable rules to alert you before your gut kicks in.

    "Moreover looking at types of cohesion can give a decent idea of what elements can be grouped together."

    True, understanding the different ways things can be associated can help. But there’s quite a bit of subjectivity. Maybe that’s unavoidable, but the article (and perhaps most similar articles) don’t go far enough in discussion concrete, repeatable practices to deal with this, or discussing why this may not even be possible.

    It is very much like design articles that advocate being "simple" without offering a compelling definition of simple or how you actually achieve it.

    But that’s the hard part.

    (Also, I have to wonder to what extent this is more a problem with OOP and less with FP. )

    This comment was originally posted on Hacker News

  4. abhirakshit says:

    I know that methods and classes mutate and their functionalities change over time. And the day it ’strikes you :) ’ that it has become gnarly it is time to refactor. How you proceed to do that is a different issue.Personally I haven’t come across a set of guidelines having more in-depth solution than what I have tried to mentioned here which works in all cases. It is a question quite dependent on the type of project you are working on. I think the best person who can properly direct you is the Architect or somebody with experience who knows the project thoroughly.

    This comment was originally posted on Hacker News

  5. jamesbritt says:

    In wondering about the funky nature of this problem, it occurred to me that it is an exercise in taxonomy. "There are only two hard problems in Computer Science: cache invalidation and naming things." — Phil KarltonCoupling and coherence are essentially about naming things, about identifying the core nature of something.

    This comment was originally posted on Hacker News

    Please continue discussion on the forum: link

Leave a Reply

Additional comments powered by BackType


[ bbPress synchronization by bobrik ]