Coupling and Cohesion in Java

Naveen AnamaneniUpdated · 5 min read

Two questions tell you a lot about a design. How much does each class depend on the others? That's coupling, and you want it low: changing one class shouldn't force changes in many others. How focused is each class on one job? That's cohesion, and you want it high: everything inside a class should belong together. Nearly every design principle in the Object-Oriented Design chapter is a way of lowering coupling or raising cohesion.

Tight Coupling, Then Loose

Depend on an interface, receive the object from outside
Tight.java
public class Tight {
    static class EmailSender {
        void sendEmail(String to, String text) {
            System.out.println("Email to " + to + ": " + text);
        }
    }
 
    static class OrderService {
        void placeOrder(String customer, long amount) {
            // business logic ...
            EmailSender sender = new EmailSender();   // welded in
            sender.sendEmail(customer, "Order of Rs. " + amount + " placed");
        }
    }
}
Output
Email to Navika: Order of Rs. 1299 placed
SMS to Advitha: Order of Rs. 450 placed

How it works

  1. In the tightly coupled version, OrderService creates an EmailSender itself and calls its specific method. Switching to SMS, or testing without sending real emails, means editing OrderService.
  2. In the loosely coupled version, OrderService depends only on the Notifier interface, and the actual notifier is passed in through the constructor.
  3. The same OrderService code sends an email for Navika and an SMS for Advitha. In a test, you could pass a fake notifier that just records messages.

Passing dependencies in from outside, instead of creating them inside, is called dependency injection. Frameworks like Spring automate it.

Coupling

Tight couplingLoose coupling
Creates collaborators with new inside methodsReceives them through constructors
Depends on concrete classesDepends on interfaces
Reaches into other objects' fieldsCalls their public methods
One change ripples through many classesChanges stay local
Hard to test in isolationEasy to test with fakes

Cohesion

A class with low cohesion does unrelated things. Imagine a Utility class with calculateGst, sendEmail, resizeImage and parseDate: every change to any feature touches it, and nobody can name what it's for. A highly cohesive class has one clear purpose and a name that says it: GstCalculator, EmailNotifier, InvoicePrinter.

Low cohesionHigh cohesion
"And" in the description: "saves orders and sends emails and prints PDFs"One responsibility: "prices an order"
Methods share no fieldsMethods work on the same data
Grows forever ("god class")Stays small and stable
Hard to reuse or testEasy to reuse and test

Common Mistakes

new everywhere inside business logic. Each new ConcreteClass() is a hard-wired dependency; pass it in instead.

"Manager" and "Util" classes that collect everything. Split them by responsibility.

Interfaces for everything, even with one implementation that will never change. Loose coupling is a tool, not a rule; use it where change or testing is likely.

Interview Corner

What are coupling and cohesion?

Coupling is the degree to which one class depends on others; low coupling means classes interact through small, stable interfaces and can change independently. Cohesion is how closely the responsibilities inside one class are related; high cohesion means a class has a single, focused purpose. Good designs aim for low coupling and high cohesion, which makes code easier to change, test and reuse.

How do you reduce coupling in Java?

Program to interfaces rather than concrete classes, inject dependencies through constructors instead of creating them with new inside methods, keep fields private and expose behavior through methods, and keep each class's public surface small.

Practice

  1. Easy: Add a WhatsAppNotifier to Loose.java and use it for Srihitha's order. Which classes did you have to change?
  2. Harder: Write a ReportService that loads data, formats it as text and saves it to a file, all in one class. Split it into three cohesive classes connected by interfaces.

Quick check: Coupling and cohesion

4 questions
1Which do good designs aim for?
2Which reduces coupling?
3A class that saves orders, sends emails and resizes images has:
4Passing dependencies into a class instead of creating them inside is called:

Key Takeaways

Was this tutorial helpful?

Lesson 167 of 482