🔍 What is Coupling in Java?
Coupling refers to the degree of dependency between two classes or modules.
- 🤝 Tight Coupling = Classes are strongly dependent on each other.
- 🪢 Loose Coupling = Classes are independent and interact via abstraction.
🚨 Tight Coupling (Bad Design Practice)
A tightly coupled class knows too much about another class. Changes in one class can break the other.
🔧 Example: Tight Coupling
class Engine {
public void start() {
System.out.println("Engine started");
}
}
class Car {
Engine engine = new Engine(); // Direct dependency
public void drive() {
engine.start();
System.out.println("Car is driving");
}
}
❌ Problems:
- You can’t switch to another engine easily (e.g., ElectricEngine).
- Hard to unit test
Car
without initializingEngine
. - Changes in
Engine
might breakCar
.
✅ Loose Coupling (Preferred Approach)
In a loosely coupled design, classes depend on abstractions (interfaces), not concrete implementations.
🌟 Benefits of Loose Coupling:
- Easy to test (you can mock dependencies).
- Easy to extend or replace components.
- Promotes cleaner design and maintainability.
🔧 Example: Loose Coupling with Interface
interface Engine {
void start();
}
class PetrolEngine implements Engine {
public void start() {
System.out.println("Petrol engine started");
}
}
class Car {
private Engine engine;
// Inject engine via constructor
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving");
}
}
✅ Usage
public class Main {
public static void main(String[] args) {
Engine engine = new PetrolEngine();
Car car = new Car(engine);
car.drive();
}
}
🔧 How Spring Framework Promotes Loose Coupling
Spring achieves loose coupling using:
- ✅ Dependency Injection
- ✅ Interfaces and Annotations (
@Autowired
,@Service
, etc.) - ✅ IoC Container (Inversion of Control)
You don’t create dependencies manually — Spring injects them for you.
🔁 Real Example Using Spring Boot
public interface NotificationService {
void send(String message);
}
@Service
public class EmailService implements NotificationService {
public void send(String message) {
System.out.println("Email sent: " + message);
}
}
@RestController
public class NotificationController {
private final NotificationService service;
@Autowired
public NotificationController(NotificationService service) {
this.service = service;
}
@GetMapping("/notify")
public String notifyUser() {
service.send("Welcome!");
return "Notification sent!";
}
}
You can easily swapEmailService
withSmsService
— the controller doesn’t need to change at all!
🔍 Summary: Tight vs. Loose Coupling

Final Thoughts
- Avoid tight coupling whenever possible.
- Embrace interfaces, dependency injection, and composition.
- Spring Boot helps you build loosely coupled, maintainable applications by default.
💡 Tight coupling makes your code rigid. Loose coupling makes it adaptable.
Comments
Post a Comment
Leave Comment