SOLID Principles

This post is a personal reference for revising SOLID principles — written in a natural tone, with quick explanations and Java examples.
🔹 1. Single Responsibility Principle (SRP)
Every class should have one responsibility — a single reason to change. Helps in identifying when to break classes.
👉 “One responsibility” = one reason to change.
// SRP violation
class InvoiceManager {
void calculateTotal() { ... }
void printInvoice() { ... } // printing shouldn't live here
}
// SRP applied
class InvoiceCalculator {
void calculateTotal() { ... }
}
class InvoicePrinter {
void printInvoice() { ... }
}
🔹 2. Open/Closed Principle (OCP)
Every class should be open to extension, but closed to modification.
We should not be touching existing ones.
Usually, violations are fixed by Factory/Strategy patterns etc., or polymorphism.
// OCP violation
class NotificationService {
void send(String type) {
if (type.equals("email")) { ... }
else if (type.equals("sms")) { ... }
}
}
// OCP applied
interface Notifier {
void send();
}
class EmailNotifier implements Notifier {
public void send() { ... }
}
class SMSNotifier implements Notifier {
public void send() { ... }
}
🔹 3. Liskov Substitution Principle (LSP)
All the child classes should be able to replace their parent class.
It helps to identify correct inheritance patterns.
A real-world is-a relation doesn’t always translate to an inheritance in OOD.
👉 Hint to identify – Tell, don’t ask (if you're checking types or behavior before calling a method, probably a violation)
❌ Violation example:
class Bird {
void fly() { System.out.println("Flying..."); }
}
class Ostrich extends Bird {
@Override
void fly() {
throw new UnsupportedOperationException("Ostrich can't fly!");
}
}
✅ LSP applied:
interface Bird { }
interface FlyingBird extends Bird {
void fly();
}
class Sparrow implements FlyingBird {
public void fly() {
System.out.println("Sparrow flying");
}
}
class Ostrich implements Bird {
// no fly method
}
🔹 4. Interface Segregation Principle (ISP)
Pretty similar to SRP, each interface should be separated based on responsibility.
Helps in deciding right abstraction.
Find fat interfaces, and break them down.
// ISP violation
interface MultiFunctionDevice {
void print();
void scan();
void fax();
}
class BasicPrinter implements MultiFunctionDevice {
public void print() { ... }
public void scan() { ... }
public void fax() { throw new UnsupportedOperationException(); }
}
// ISP applied
interface Printer {
void print();
}
interface Scanner {
void scan();
}
🔹 5. Dependency Inversion Principle (DIP)
The high-level modules should not depend on low-level modules — instead, both should depend on abstractions.
So, the dependency from high → low level module inverts to low → abstraction.
Some other concepts:
- Dependency Injection: the class should not create its own dependency — it should get it from downstream.
- Inversion of Control: If we follow the dependency injection pattern, then at the main method, the code becomes messy and difficult to manage. So we delegate object creation to some framework (like Spring IoC container).
// DIP violation
class EmailService {
void send(String msg) { ... }
}
class NotificationManager {
EmailService service = new EmailService();
void notifyUser(String msg) {
service.send(msg);
}
}
// DIP applied
interface MessageService {
void send(String msg);
}
class EmailService implements MessageService {
public void send(String msg) { ... }
}
class NotificationManager {
private final MessageService service;
NotificationManager(MessageService service) {
this.service = service;
}
void notifyUser(String msg) {
service.send(msg);
}
}
🔁 Final Thoughts
- SRP and OCP sort of follow each other. If a class is created with limited and well-defined responsibility, it's rare that we touch it later — because it’s already well implemented.
- Also, Dependency Inversion is only possible if LSP and ISP are followed well.
- These principles are not meant to be applied rigidly — the goal is to build systems that are easier to change, test, and scale.
📝 This post was written for personal revision, but feel free to adapt or share it if you find it useful.
Subscribe to my newsletter
Read articles from Kishan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
