Coupling & Cohesion
Two fundamental metrics for measuring the quality of your software design.
The Golden Rule
Low Coupling + High Cohesion = Good Design
This is what you should always aim for.
Coupling (Between Modules)
Coupling measures how dependent modules are on each other. High coupling means changes in one module require changes in others.
High Coupling (Bad)
class OrderService {
// Directly depends on
// concrete classes
MySQLDatabase db;
SmtpEmailer emailer;
StripePayment payment;
void process() {
db.query("SELECT...");
emailer.send(...);
payment.charge(...);
}
}- - Hard to test (need real DB, email, payment)
- - Hard to change (switch DB = rewrite code)
- - Ripple effect of changes
Low Coupling (Good)
class OrderService {
// Depends on interfaces
Database db;
Emailer emailer;
PaymentGateway payment;
// Inject dependencies
OrderService(Database d,
Emailer e,
PaymentGateway p) {
this.db = d;
this.emailer = e;
this.payment = p;
}
}- - Easy to test with mocks
- - Easy to swap implementations
- - Changes are isolated
Types of Coupling (Worst to Best)
Content- One class modifies internal data of another
WorstCommon- Multiple classes share global data
BadControl- One class controls behavior of another
PoorStamp- Classes share composite data structures
MediumData- Classes communicate via simple parameters
GoodMessage- Classes communicate via well-defined interfaces
BestCohesion (Within a Module)
Cohesion measures how focused a module is on a single purpose. High cohesion means all parts of a module work together for one goal.
Low Cohesion (Bad)
// "God class" - does everything
class Utils {
void sendEmail() {...}
void formatDate() {...}
void validateUser() {...}
void calculateTax() {...}
void resizeImage() {...}
void parseJSON() {...}
}- - Unrelated methods grouped together
- - Hard to understand purpose
- - Changes affect unrelated features
High Cohesion (Good)
// Each class has one focus
class EmailService {
void send() {...}
void validate() {...}
void format() {...}
}
class DateFormatter {
String format() {...}
Date parse() {...}
}
class TaxCalculator {
double calculate() {...}
double getRate() {...}
}- - Related methods grouped together
- - Clear purpose for each class
- - Easy to understand and maintain
Types of Cohesion (Worst to Best)
Coincidental- Random methods grouped together
WorstLogical- Methods loosely related by category
BadTemporal- Methods called at the same time
PoorProcedural- Methods follow a sequence
MediumCommunicational- Methods work on same data
GoodFunctional- All methods contribute to single task
BestVisual Summary
Coupling
Tight
Bad
→
Loose
Good
Cohesion
Low
Bad
→
High
Good
Interview Tips
- 1.Low Coupling = classes are independent (use interfaces, DI)
- 2.High Cohesion = class does one thing well (SRP)
- 3.These are related to SOLID principles (especially SRP and DIP)
- 4.When reviewing code, ask: "Is this class doing too much? Is it too dependent?"