LLD/Design Principles

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
Worst
Common- Multiple classes share global data
Bad
Control- One class controls behavior of another
Poor
Stamp- Classes share composite data structures
Medium
Data- Classes communicate via simple parameters
Good
Message- Classes communicate via well-defined interfaces
Best

Cohesion (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
Worst
Logical- Methods loosely related by category
Bad
Temporal- Methods called at the same time
Poor
Procedural- Methods follow a sequence
Medium
Communicational- Methods work on same data
Good
Functional- All methods contribute to single task
Best

Visual 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?"