Amr Ayman

SOLID Principles ExpLained WITH EXAMPLES
🕑 8 mins
As software systems grow, code can become hard to understand, scale, and maintain. That’s why SOLID principles is needed.
SOLID is a set of five object-oriented design principles introduced by Robert C. Martin (Uncle Bob) that help developers build scalable, readable, and maintainable software projects.
SOLID stands for:
- Single Responsibility Principle (SRP)
- Open/Closed Principle (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
Let’s Get into each point !
Single Responsibility Principle (SRP)
Each class should have one responsibility, not multiple unrelated tasks.
Bad Practice:
This class manages User and Emails.
Java
public class UserManager {
public void saveUser(User user) {
// save user to database
}
public void sendEmail(User user) {
// send email
}
}Good Practice:
Java
public class UserRepository {
public void saveUser(User user) {
// save user
}
}
public class EmailService {
public void sendEmail(User user) {
// send email
}
}Open/Closed Principle (OCP)
Classes should be open for extension but closed for modification. So adding new behavior should be done without changing the existing code.
Bad Practice:
Adding a new payment method requires modifying this class.
Java
public class PaymentService {
public void pay(String type) {
if (type.equals("CARD")) {
// card payment
} else if (type.equals("CASH")) {
// cash payment
}
}
}Good Practice:
Java
public interface Payment {
void pay();
}
public class CardPayment implements Payment {
@Override
public void pay() {
// card payment logic
}
}
public class CashPayment implements Payment {
@Override
public void pay() {
// cash payment logic
}
}Liskov Substitution Principle (LSP)
Objects of a parent class can be replaced by its children without breaking functionality.
Bad Practice:
not all birds can fly.
Java
public class Bird {
public void fly() {
// fly logic
}
}
public class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Penguins can't fly");
}
}Good Practice:
Java
public interface Bird {
}
public interface FlyingBird extends Bird {
void fly();
}
public class Sparrow implements FlyingBird {
@Override
public void fly() {
// flying
}
}
public class Penguin implements Bird {
}Interface Segregation Principle (ISP)
Clients should not depend on interfaces they do not use.
Bad Practice:
Robots don’t eat, but they are forced to implement eat().
Java
public interface Worker {
void work();
void eat();
}
public class HumanWorker implements Worker {
public void work() {}
public void eat() {}
}
public class RobotWorker implements Worker {
public void work() {}
public void eat() {}
}Good Practice:
Java
public interface Workable {
void work();
}
public interface Eatable {
void eat();
}
public class HumanWorker implements Workable, Eatable {
public void work() {}
public void eat() {}
}
public class RobotWorker implements Workable {
public void work() {}
}Dependency Inversion Principle (DIP)
High-level modules should depend on abstractions, not concrete implementations.
Bad Practice:
Java
public class OrderService {
private MySqlDatabase database = new MySqlDatabase();
}Good Practice:
Java
public interface Database {
void save();
}
public class MySqlDatabase implements Database {
@Override
public void save() {
// save to MySQL
}
}
public class OrderService {
private final Database database;
public OrderService(Database database) {
this.database = database;
}
}Always Write code that is easy to understand, test, and extend, and follow SOLID to achieve that!



