Introduction
Good software design depends heavily on low coupling and high cohesion. These principles define how classes interact and how focused each class is on its responsibility.
Why It Matters
- Improves maintainability and readability.
- Enhances testability and reusability.
- Reduces bugs when making changes.
When to Use
- Always consider coupling and cohesion when designing classes, packages, and modules.
- Especially critical in large-scale enterprise applications.
Core Concepts
What is Coupling?
Coupling measures the degree of dependency between modules/classes.
- Tight Coupling: Classes are heavily dependent on each other.
- Loose Coupling: Classes have minimal dependencies.
What is Cohesion?
Cohesion measures how focused and related the responsibilities of a single class or module are.
- Low Cohesion: A class does many unrelated tasks.
- High Cohesion: A class does one well-defined task.
Real-World Analogy
- Coupling: Think of coupling as friendship. If you depend on one friend for everything, you’re tightly coupled.
- Cohesion: Think of cohesion as a restaurant menu. A pizzeria with only pizza items is cohesive; one serving pizza, sushi, and burgers has low cohesion.
Comparison Table
Aspect | Coupling | Cohesion |
---|---|---|
Definition | Dependency between modules | Focus within a module |
Goal | Keep it low | Keep it high |
Impact | High coupling reduces flexibility | High cohesion improves maintainability |
Measurement | External relationships | Internal responsibility |
Real-World Use Cases
- Low Coupling: Service classes communicating via interfaces in Spring.
- High Cohesion: A
UserService
handling only user-related logic.
Example: Tight vs Loose Coupling
Tightly Coupled:
class Engine {
void start() { System.out.println("Engine started"); }
}
class Car {
Engine engine = new Engine(); // Direct dependency
void drive() { engine.start(); }
}
Loosely Coupled:
interface Engine {
void start();
}
class PetrolEngine implements Engine {
public void start() { System.out.println("Petrol Engine started"); }
}
class Car {
private Engine engine;
Car(Engine engine) { this.engine = engine; }
void drive() { engine.start(); }
}
Performance & Memory Implications
- Coupling and cohesion are design-time concepts, but they affect runtime performance indirectly.
- High cohesion improves caching and code locality.
- Low coupling reduces recompilation and redeployment impact.
Common Mistakes & Anti-Patterns
- God Classes:
- Classes that do everything have low cohesion.
- Direct Object Instantiation Everywhere:
- Leads to tight coupling; use dependency injection.
- Mixing Unrelated Logic:
- Erodes cohesion and makes code harder to test.
Best Practices
- Favor interfaces and dependency injection.
- Apply the Single Responsibility Principle for cohesion.
- Refactor large classes into smaller cohesive units.
- Use design patterns like Strategy, Factory for loose coupling.
Java Version Relevance
Version | Change |
---|---|
Java 5+ | Generics improved type-safe low coupling |
Java 8+ | Lambdas and streams improved cohesion in functional-style code |
Code Example: High Cohesion and Low Coupling
interface PaymentProcessor {
void processPayment(double amount);
}
class CreditCardProcessor implements PaymentProcessor {
public void processPayment(double amount) {
System.out.println("Processing credit card: " + amount);
}
}
class OrderService {
private final PaymentProcessor processor;
public OrderService(PaymentProcessor processor) {
this.processor = processor;
}
public void checkout(double amount) {
processor.processPayment(amount);
}
}
Conclusion & Key Takeaways
- Aim for low coupling and high cohesion in all Java code.
- Improves maintainability, testability, and flexibility.
- Use interfaces, dependency injection, and SRP to achieve these goals.
FAQ
-
What is coupling in Java?
The degree of dependency between classes or modules. -
What is cohesion in Java?
How focused a class/module is on a single responsibility. -
Why is low coupling important?
It makes code flexible and easier to modify. -
Why is high cohesion important?
It makes code maintainable and readable. -
How to achieve low coupling?
Use interfaces, DI, and design patterns. -
How to achieve high cohesion?
Follow SRP; keep classes focused. -
Does low coupling affect performance?
Indirectly; improves modularity and reduces ripple effects. -
Can a class be highly cohesive and tightly coupled?
Yes, but aim to reduce coupling via interfaces. -
What’s a God class?
A class with low cohesion doing too many tasks. -
Do coupling and cohesion apply only to classes?
No, also to packages, modules, and microservices.