SOLID Principles

Intermediate · 24 min read · Low-Level Design, Design Principles

Five principles with violations, fixes and the trade-offs of over-applying them.

SOLID is five principles, popularised by Robert C. Martin, for designing classes that are easy to change. Almost every LLD interview touches them — either directly ("explain Liskov with an example") or by asking you to extend your design and watching whether it bends or breaks.

The idea in plain words

All five rules aim at one thing: when requirements change, you should have to touch as little working code as possible.

S — Single Responsibility Principle

"Responsibility" is best understood as a source of change: a group of people or a requirement area that could ask for modifications.

O — Open/Closed Principle

Add new behaviour by adding new code (a new class), not by editing existing, tested code. The usual mechanism is polymorphism behind an interface.

L — Liskov Substitution Principle

A subclass must honour the behavioural contract of its parent — not just compile.

I — Interface Segregation Principle

Benefits: implementers aren't forced into UnsupportedOperationException stubs (an LSP violation), and clients depending on Printer don't recompile or redeploy when fax features change.

D — Dependency Inversion Principle

The "inversion": the source-code dependency now points from the low-level detail toward the high-level policy, opposite to the flow of control. Three practical steps:

How SOLID shows up in an interview

When the interviewer adds a requirement — "now support UPI payments", "add a weekend surcharge" — narrate the principle:

Interview questions

  • Explain the Liskov Substitution Principle with an example that isn't Rectangle/Square.
  • Doesn't the Open/Closed Principle lead to too many classes?
  • What's the difference between Dependency Inversion and Dependency Injection?
  • How does ISP relate to LSP?

Further reading

Key takeaways

  • SRP: one reason to change — group by source of change, not by method count.
  • OCP: extend through new classes behind interfaces along the axes that really vary.
  • LSP: subtypes must honour the parent's contract — no stronger preconditions, weaker guarantees or surprise exceptions.
  • ISP: role-based interfaces sized to what clients use.
  • DIP: business logic owns abstractions; infrastructure implements them; inject via constructors.
  • All five are trade-offs — apply them where change is expected.

Previous: Class Relationships & UML · Next: Core Design Principles