SOLID principles are the foundation of good Low Level Design. In interviews at Amazon, Flipkart, Google, and other top companies, interviewers expect you to not just know these principles by name but to apply them naturally in your class design. This guide explains each principle with concrete LLD examples.
Why SOLID Matters in LLD Interviews
Most candidates can recite the SOLID acronym. Few can apply it. Interviewers test SOLID indirectly — they ask "how would you add a new feature?" or "what's the problem with this design?" If you understand SOLID, you instantly spot the issues and propose clean solutions.
S — Single Responsibility Principle
"A class should have only one reason to change."
Violation:
class ParkingLot {
parkVehicle(v: Vehicle): void { ... }
calculateFee(ticket: Ticket): number { ... } // Wrong!
sendSMSAlert(msg: string): void { ... } // Wrong!
generateReport(): string { ... } // Wrong!
}Fix: Each responsibility gets its own class — ParkingLot, FeeCalculator, NotificationService, ReportGenerator.
Interview tip: When you see a class doing multiple unrelated things, mention SRP and split it. This is the most commonly violated principle and easiest to spot.
O — Open/Closed Principle
"Open for extension, closed for modification."
Violation:
class FeeCalculator {
calculate(vehicle: Vehicle): number {
if (vehicle.type === "BIKE") return 20;
if (vehicle.type === "CAR") return 40;
if (vehicle.type === "TRUCK") return 80;
// Adding electric vehicle requires modifying this class ❌
}
}Fix: Strategy pattern — each vehicle type implements its own pricing strategy. Adding a new vehicle never touches existing code.
interface PricingStrategy { calculateFee(duration: number): number; }
class BikePricing implements PricingStrategy { calculateFee(d) { return 20 * Math.ceil(d/60); } }
class CarPricing implements PricingStrategy { calculateFee(d) { return 40 * Math.ceil(d/60); } }
// Add ElectricCarPricing without touching anything ✓L — Liskov Substitution Principle
"Subclasses must be substitutable for their base class."
Violation:
class Rectangle { setWidth(w) { this.width = w; } setHeight(h) { this.height = h; } }
class Square extends Rectangle {
setWidth(w) { this.width = w; this.height = w; } // Breaks Rectangle contract ❌
}In LLD interviews: If your PaymentMethod base class has a processRefund() method but CashPayment can't support refunds, LSP is violated. Either redesign the hierarchy or use a separate RefundablePayment interface.
I — Interface Segregation Principle
"Clients should not be forced to depend on interfaces they don't use."
Violation:
interface Vehicle {
getSpeed(): number;
fly(): void; // Not all vehicles can fly ❌
sail(): void; // Not all vehicles can sail ❌
}
class Car implements Vehicle {
fly() { throw new Error("Cars can't fly"); } // Forced to implement ❌
}Fix: Split into Driveable, Flyable, Sailable interfaces. Classes implement only what applies.
Interview tip: Watch for fat interfaces. In a Notification system, don't have one giant NotificationService — split into EmailSender, SMSSender, PushSender with a shared Notifier interface.
D — Dependency Inversion Principle
"Depend on abstractions, not concretions."
Violation:
class OrderService {
private db = new MySQLDatabase(); // Tightly coupled to MySQL ❌
saveOrder(order: Order) { this.db.save(order); }
}Fix: Inject the abstraction:
interface Database { save(entity: any): void; }
class OrderService {
constructor(private db: Database) {} // Works with MySQL, MongoDB, in-memory ✓
saveOrder(order: Order) { this.db.save(order); }
}In LLD interviews: When you use constructor injection for strategies, repositories, and services — you're applying DIP. This is what makes systems testable and swappable.
How to Apply SOLID in an Interview
You don't need to name-drop "Single Responsibility Principle" every 5 minutes. Instead, let your design speak:
- When splitting classes: "I'm keeping pricing logic separate so changes to fee structure don't affect the parking lot code"
- When using interfaces: "I'm depending on this abstraction so we can swap implementations later"
- When the interviewer asks "how would you add X": "Since we used Strategy here, we just add a new class — nothing else changes"
SOLID Quick Reference for LLD Problems
- Parking Lot: SRP (split ParkingLot/FeeCalculator), OCP (Strategy for pricing), DIP (inject PricingStrategy)
- Notification System: ISP (split channel interfaces), OCP (add new channels without modifying core)
- Payment Gateway: OCP (new payment method = new class), LSP (all PaymentMethod subclasses support charge())
- Chat App: SRP (split MessageService/UserService/NotificationService), DIP (inject MessageStore)