Skip to content

SOLID Principles — Detailed#

classDiagram
  direction LR
  class SRP {
    +Single Responsibility
    +A class has ONE reason to change
    +Split classes by axis of change
  }
  class OCP {
    +Open / Closed
    +Open for extension
    +Closed for modification
    +Use interfaces + polymorphism
  }
  class LSP {
    +Liskov Substitution
    +Subtypes must be usable wherever
    +base type is expected
    +preserve contracts
  }
  class ISP {
    +Interface Segregation
    +Clients shouldn't depend on
    +methods they don't use
    +Many small interfaces - one fat one
  }
  class DIP {
    +Dependency Inversion
    +Depend on abstractions
    +not concretions
    +High-level modules don't import
    +low-level details
  }
  SRP --> OCP
  OCP --> LSP
  LSP --> ISP
  ISP --> DIP

Each principle in one sentence#

Principle Tells you to... Smell when violated
S ingle Responsibility give each class one reason to change "And"-named classes; methods touch unrelated state
O pen / Closed extend behaviour by adding new types, not editing old ones sprawling if (type == ...) chains
L iskov Substitution make subclasses substitutable for their base type if (instanceof Square) workarounds; thrown UnsupportedOperationException
I nterface Segregation split fat interfaces so clients only see what they use classes implementing 20 methods to satisfy 1 caller
D ependency Inversion depend on abstractions, inject concretions from outside new HttpClient() inside a domain class

Worked example: OCP#

Before (violates OCP — every new shape needs an edit to area()):

class AreaCalculator {
  double area(Shape s) {
    if (s instanceof Circle)    return Math.PI * ((Circle)s).r * ((Circle)s).r;
    if (s instanceof Rectangle) return ((Rectangle)s).w * ((Rectangle)s).h;
    throw new IllegalArgumentException();
  }
}

After (open for extension — add a new shape, no edits to existing code):

interface Shape { double area(); }
class Circle implements Shape    { public double area() { return Math.PI * r * r; } }
class Rectangle implements Shape { public double area() { return w * h; } }
class AreaCalculator {
  double area(Shape s) { return s.area(); }
}

How SOLID shows up in this site#

Most of the LLD-flavoured designs (Parking Lot, Elevator, Vending Machine, ATM, Chess, Logger) rely on: - SRP to split state / pricing / dispatch into separate classes. - OCP + LSP to add new vehicle types / piece types / payment methods without editing the core. - DIP to inject payment gateways, storage backends, time sources.

Glossary & fundamentals#

Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.

Tag Concept What it is Page
LLD OOP pillars encapsulation, abstraction, inheritance, polymorphism oop-pillars
LLD SOLID principles SRP / OCP / LSP / ISP / DIP solid-principles
LLD Error handling exceptions vs Result, error boundaries error-handling