1.
S: Single Responsibility Principle (SRP)
Concept: A class should have one, and only one, reason to change.
In simple terms: "Ek kaam, ek class." Don't make your class a "Sarva Guna Sampann" hero that
does everything.
Bad Implementation: The "All-in-One" Order Service
Imagine a SwiggyOrderService that validates the order, saves it to the DB, and sends a
WhatsApp notification.
Java
// BAD: This class is doing way too much!
public class OrderService {
public void processOrder(Order order) {
// 1. Business Logic
if ([Link]().isEmpty()) throw new RuntimeException("Empty cart!");
// 2. Database Logic
[Link]("Saving order to MySQL database...");
// 3. Notification Logic
[Link]("Sending WhatsApp notification to customer...");
}
}
Why it’s bad: If the DB team switches from MySQL to MongoDB, you have to touch this class. If
the Marketing team wants to switch from WhatsApp to Email, you touch the same class. It’s like
a Chai-wala who also tries to fix your laptop while making tea—both the tea and the laptop will
suffer.
Good Implementation: Refactored SRP
Java
// GOOD: Each class has one job.
class OrderValidator {
public void validate(Order order) { /* Validation logic */ }
}
class OrderRepository {
public void save(Order order) { /* DB logic */ }
}
class NotificationService {
public void notify(Order order) { /* WhatsApp/Email logic */ }
}
// The main service just orchestrates
public class OrderService {
private OrderValidator validator;
private OrderRepository repository;
private NotificationService notification;
public void processOrder(Order order) {
[Link](order);
[Link](order);
[Link](order);
}
}
2. O: Open/Closed Principle (OCP)
Concept: Software entities should be Open for extension, but Closed for modification.
You should be able to add new features without touching the existing, tested code.
Bad Implementation: The "If-Else" Nightmare
Imagine Flipkart adding a new payment mode.
Java
// BAD: Every time a new payment method (UPI) comes, we modify this class.
public class PaymentProcessor {
public void processPayment(String type) {
if ([Link]("CreditCard")) {
// Logic
} else if ([Link]("DebitCard")) {
// Logic
} else if ([Link]("UPI")) { // Added later, modified existing code
// Logic
}
}
}
Why it’s bad: Modifying existing code is risky. It’s like breaking the foundation of a building just
to add a new balcony. You might accidentally break the Credit Card logic while adding UPI.
Good Implementation: Using Interfaces
Java
interface PaymentMethod {
void pay();
}
class CreditCardPayment implements PaymentMethod {
public void pay() { [Link]("Paid via Credit Card"); }
}
class UPIPayment implements PaymentMethod {
public void pay() { [Link]("Paid via UPI (PhonePe/GPay)"); }
}
// This class is now CLOSED for modification.
// Want to add "Crypto"? Just create a new class!
public class PaymentProcessor {
public void process(PaymentMethod method) {
[Link]();
}
}
3. L: Liskov Substitution Principle (LSP)
Concept: Objects of a superclass should be replaceable with objects of its subclasses without
breaking the application.
Basically: "Don't lie in your inheritance." If a subclass can't do what the parent claims to do,
don't inherit.
Bad Implementation: The "Square-Rectangle" Trap
Java
class Rectangle {
protected int width, height;
public void setWidth(int w) { [Link] = w; }
public void setHeight(int h) { [Link] = h; }
}
class Square extends Rectangle {
@Override
public void setWidth(int w) {
[Link](w);
[Link](w); // Forcing height to match width
}
}
Why it’s bad: If a developer writes a function that expects a Rectangle and calculates area by
changing the width, the Square will behave unexpectedly because it changes the height too. It’s
like ordering a "Veg Biryani" and getting "Pulao"—they look similar, but the expectations are
different!
Good Implementation
Avoid forced inheritance. If they behave differently, use a common interface like Shape or keep
them separate.
4. I: Interface Segregation Principle (ISP)
Concept: A client should never be forced to implement an interface it doesn't use.
"Don't give a 10-page menu to someone who just wants Chai."
Bad Implementation: The "Fat" Interface
Java
interface WiproEmployee {
void writeCode();
void attendClientMeetings();
void fixBugs();
void approveBudgets();
}
class JuniorDeveloper implements WiproEmployee {
public void writeCode() { /* Yes */ }
public void fixBugs() { /* Yes */ }
public void attendClientMeetings() { /* Not really */ }
public void approveBudgets() { /* I wish! */ } // Forced to implement
}
Why it’s bad: The JuniorDeveloper is forced to implement approveBudgets, which makes no
sense. The interface is too "fat."
Good Implementation: Lean Interfaces
Java
interface Codeable { void writeCode(); }
interface BugFixable { void fixBugs(); }
interface Manageable { void approveBudgets(); }
class JuniorDev implements Codeable, BugFixable {
public void writeCode() { /* ... */ }
public void fixBugs() { /* ... */ }
}
class DeliveryManager implements Manageable {
public void approveBudgets() { /* ... */ }
}
5. D: Dependency Inversion Principle (DIP)
Concept: High-level modules should not depend on low-level modules. Both should depend
on abstractions.
In short: "Don't hardcode dependencies."
Bad Implementation: Hardcoded Dependency
Java
class MySQLDatabase {
public void saveOrder() { /* ... */ }
}
public class OrderManager {
// Problem: Hardcoded to MySQL!
private MySQLDatabase db = new MySQLDatabase();
public void save() { [Link](); }
}
Why it’s bad: OrderManager (High level) is now a slave to MySQLDatabase (Low level). If you
want to use Oracle or MongoDB, you have to rewrite the OrderManager. It's like a TV remote
that only works with one specific brand of battery.
Good Implementation: Dependency Injection
Java
interface Database {
void save();
}
class MongoDB implements Database {
public void save() { [Link]("Saved in Mongo"); }
}
public class OrderManager {
private Database db;
// The 'Abstraction' is injected. Flexible!
public OrderManager(Database db) {
[Link] = db;
}
public void save() { [Link](); }
}
Why does this matter?
Working at Wipro, we deal with massive enterprise projects. Without SOLID:
1. Regression bugs will haunt you.
2. Unit testing will be impossible.
3. Onboarding new joiners will take months because the code is a "Maze."
Apply these, and your code will be as smooth as a 100-GE connection!