Day 5 - Learn SOLID Design Principles: Detailed Guide and Practical Code Samples part -1.


1) Why Design Principles Matter?
Without proper design principles, our code becomes:
❌ Difficult to Maintain
❌ Hard to Read
❌ Bugs
This is where SOLID Principles come to the rescue!
2) SOLID Design Principles
💠 Introduction to SOLID Principles
Back in the year 2000, a computer scientist named Robert C. Martin (aka Uncle Bob) introduced five key principles of object-oriented programming to write better, scalable, and maintainable code.
SOLID is a set of five basic design principles in object-oriented programming that help developers write clean, easy-to-maintain, and scalable code. These principles improve the structure of your code and make it easier to understand and modify. Following the principles keeps the code structured and ready for future updates.
(Hindi : SOLID ek paanch core design principles ka set hai jo object-oriented programming mein clear, samajhne mein easy, aur maintain karne layak code likhne mein madad karta hai. In principles ko follow karne se code structured rehta hai aur future updates ke liye ready hota hai.)
They are remembered as the acronym: SOLID
The five SOLID principles are:
S – Single Responsibility Principle (SRP)
O – Open/Closed Principle
L – Liskov Substitution Principle (LSP)
I – Interface Segregation Principle (ISP) ❌ (we’ll skip this for now)
D – Dependency Inversion Principle (DIP) ❌ (we’ll skip this too)
1. Single Responsibility Principle (SRP)
A class should have only one reason to change. That means one class = one job.
A class should do only one things.
📍Real-Life Example:
Think of a washing machine. Its only job is to wash clothes. Imagine if it also tried to make tea — that’s bad design.
(Hindi: Ek washing machine ka kaam sirf kapde dhona hona chahiye. Agar woh chai banana bhi shuru kar de, toh system kaam nahi karega.)
Note: Ek class ke andar multiple methods ho sakta hai, lekin uska purpose and responsibility ek hi specific task se related hona chahiye.
import java.util.ArrayList;
import java.util.List;
// Product class representing any item in eCommerce.
class Product {
public String name;
public double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
}
// 1. ShoppingCart: Only responsible for Cart related business logic.
class ShoppingCart {
private List<Product> products = new ArrayList<>();
public void addProduct(Product p) {
products.add(p);
}
public List<Product> getProducts() {
return products;
}
// Calculates total price in cart.
public double calculateTotal() {
double total = 0;
for (Product p : products) {
total += p.price;
}
return total;
}
}
// 2. ShoppingCartPrinter: Only responsible for printing invoices
class ShoppingCartPrinter {
private ShoppingCart cart;
public ShoppingCartPrinter(ShoppingCart cart) {
this.cart = cart;
}
public void printInvoice() {
System.out.println("Shopping Cart Invoice:");
for (Product p : cart.getProducts()) {
System.out.println(p.name + " - Rs " + p.price);
}
System.out.println("Total: Rs " + cart.calculateTotal());
}
}
// 3. ShoppingCartStorage: Only responsible for saving cart to DB
class ShoppingCartStorage {
private ShoppingCart cart;
public ShoppingCartStorage(ShoppingCart cart) {
this.cart = cart;
}
public void saveToDatabase() {
System.out.println("Saving shopping cart to database...");
}
}
public class SRPFollowed {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.addProduct(new Product("Laptop", 50000));
cart.addProduct(new Product("Mouse", 2000));
ShoppingCartPrinter printer = new ShoppingCartPrinter(cart);
printer.printInvoice();
ShoppingCartStorage db = new ShoppingCartStorage(cart);
db.saveToDatabase();
}
}
2. Open/Closed Principle (OCP)
A class Software should be open for extension, but closed for modification."Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"
📍 Real-Life Example:
Think of a power strip (multi-plug). You can add more devices (extend), but you don’t need to break or modify it to use it.
(Hindi: Power board mein aap naye devices laga sakte ho bina use tod-phod kiye.)
Note : Bina existing class ya code ko modify kiye naye features ko add karna
import java.util.ArrayList;
import java.util.List;
// Product class representing any item in eCommerce.
class Product {
public String name;
public double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
}
// 1. ShoppingCart: Only responsible for Cart related business logic.
class ShoppingCart {
private List<Product> products = new ArrayList<>();
public void addProduct(Product p) {
products.add(p);
}
public List<Product> getProducts() {
return products;
}
// Calculates total price in cart.
public double calculateTotal() {
double total = 0;
for (Product p : products) {
total += p.price;
}
return total;
}
}
// 2. ShoppingCartPrinter: Only responsible for printing invoices
class ShoppingCartPrinter {
private ShoppingCart cart;
public ShoppingCartPrinter(ShoppingCart cart) {
this.cart = cart;
}
public void printInvoice() {
System.out.println("Shopping Cart Invoice:");
for (Product p : cart.getProducts()) {
System.out.println(p.name + " - Rs " + p.price);
}
System.out.println("Total: Rs " + cart.calculateTotal());
}
}
interface Persistence {
void save(ShoppingCart cart);
}
class SQLPersistence implements Persistence {
@Override
public void save(ShoppingCart cart) {
System.out.println("Saving shopping cart to SQL DB...");
}
}
class MongoPersistence implements Persistence {
@Override
public void save(ShoppingCart cart) {
System.out.println("Saving shopping cart to MongoDB...");
}
}
class FilePersistence implements Persistence {
@Override
public void save(ShoppingCart cart) {
System.out.println("Saving shopping cart to a file...");
}
}
public class OCPFollowed {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.addProduct(new Product("Laptop", 50000));
cart.addProduct(new Product("Mouse", 2000));
ShoppingCartPrinter printer = new ShoppingCartPrinter(cart);
printer.printInvoice();
Persistence db = new SQLPersistence();
Persistence mongo = new MongoPersistence();
Persistence file = new FilePersistence();
db.save(cart); // Save to SQL database
mongo.save(cart); // Save to MongoDB
file.save(cart); // Save to File
}
}
3. Liskov Substitution Principle (LSP)
The principle was introduced by Barbara Liskov in 1987 and according to this principle "Derived or child classes must be substitutable for their base or parent classes".
Subclass should be substitutable for their base classes.
Any client that expects a reference of class A
(the base class) should be able to work correctly even when an object of class B
(a subclass of A) is passed instead. This means the subclass should be substitutable for the base class without breaking the functionality of the program.
📍 Real-Life Example for LSP:
Think of a universal TV remote.
It is designed to work with different TV brands — Sony, LG, Samsung — all of which follow the same basic commands (like power on/off, volume, channel change).
If the remote works fine with any of these TVs without needing internal changes, then each TV (subclass) is substitutable for the standard remote (base class).
🔁 In code terms:
Remote = base class,
SonyTV / SamsungTV = subclasses.
Each subclass should respond correctly to base class behavior — without breaking anything.
(Hindi : Socho ek universal TV remote hai — usse aap Sony, LG, Samsung kisi bhi TV ko control kar sakte ho.
Har TV remote ke basic functions (power, volume, channel) samajh leta hai.
Matlab har TV (subclass) ko ek base class ke remote ke reference se control kiya ja sakta hai — bina kuch tod-phod ke.
Yahi hai Liskov Substitution Principle.)
Note : Subclass ko parent class ke features ko extend karna hota hai, bina unki functionality ko break kiye.
import java.util.ArrayList;
import java.util.List;
// 1. DepositOnlyAccount interface: only allows deposits
interface DepositOnlyAccount {
void deposit(double amount);
}
// 2. WithdrawableAccount interface: allows deposits and withdrawals
interface WithdrawableAccount extends DepositOnlyAccount {
void withdraw(double amount);
}
class SavingAccount implements WithdrawableAccount {
private double balance;
public SavingAccount() {
balance = 0;
}
@Override
public void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount + " in Savings Account. New Balance: " + balance);
}
@Override
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
System.out.println("Withdrawn: " + amount + " from Savings Account. New Balance: " + balance);
} else {
System.out.println("Insufficient funds in Savings Account!");
}
}
}
class CurrentAccount implements WithdrawableAccount {
private double balance;
public CurrentAccount() {
balance = 0;
}
@Override
public void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount + " in Current Account. New Balance: " + balance);
}
@Override
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
System.out.println("Withdrawn: " + amount + " from Current Account. New Balance: " + balance);
} else {
System.out.println("Insufficient funds in Current Account!");
}
}
}
class FixedTermAccount implements DepositOnlyAccount {
private double balance;
public FixedTermAccount() {
balance = 0;
}
@Override
public void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount + " in Fixed Term Account. New Balance: " + balance);
}
}
class BankClient {
private List<WithdrawableAccount> withdrawableAccounts;
private List<DepositOnlyAccount> depositOnlyAccounts;
public BankClient(List<WithdrawableAccount> withdrawableAccounts,
List<DepositOnlyAccount> depositOnlyAccounts) {
this.withdrawableAccounts = withdrawableAccounts;
this.depositOnlyAccounts = depositOnlyAccounts;
}
public void processTransactions() {
for (WithdrawableAccount acc : withdrawableAccounts) {
acc.deposit(1000);
acc.withdraw(500);
}
for (DepositOnlyAccount acc : depositOnlyAccounts) {
acc.deposit(5000);
}
}
}
public class LSPFollowed {
public static void main(String[] args) {
List<WithdrawableAccount> withdrawableAccounts = new ArrayList<>();
withdrawableAccounts.add(new SavingAccount());
withdrawableAccounts.add(new CurrentAccount());
List<DepositOnlyAccount> depositOnlyAccounts = new ArrayList<>();
depositOnlyAccounts.add(new FixedTermAccount());
BankClient client = new BankClient(withdrawableAccounts, depositOnlyAccounts);
client.processTransactions();
}
}
Day 5 Completed ✅ System Design
NOTE : - A big thanks to my mentors Rohit Negi Sir and Aditya Sir for launching this amazing 8-week course absolutely free on YouTube via CoderArmy9 :- https://www.youtube.com/@CoderArmy9🙌
👉 Share this blog with your connections! Let’s keep learning, growing, and supporting one another on this journey. 🚀
✍️ Payal Kumari 👩💻
Jai Hind 🇮🇳 | #CoderArmy #LearningInPublic #SystemDesign #TechForAll #MentorshipMatters #8weeksLLdChallenge #LowLevelDesign #Code #LLD #OOP #SOLIDDesignPrinciples 👩💻
Subscribe to my newsletter
Read articles from Payal Kumari directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Payal Kumari
Payal Kumari
I'm a passionate full-stack developer with a strong foundation in the MERN stack—building and maintaining scalable web applications using React.js, Node.js, and Next.js. My journey in open source began with Hacktoberfest 2023, where I made four impactful pull requests that sparked a love for collaborative coding, global learning, and open knowledge sharing. Since then, I’ve contributed to and mentored projects in top open source programs like GSSoC’24, SSOC’24, and C4GT’24. As a Google Gen AI Exchange Hackathon ’24 Finalist and Google’s Women Techmakers (WTM) Ambassador, I’ve been privileged to support diverse communities in building meaningful tech solutions. My work as a Top 50 Mentor for GSSoC ’24 reflects my commitment to nurturing new talent in tech. Beyond development, I serve as a Student Career Guide, Profile Building Expert & Evangelist at Topmate.io, where I conduct workshops, guide students through resume building and career strategy, and help mentees navigate open source and tech careers. Recognized among the Top 5% of mentors and featured on “Topmate Discover,” I take pride in making mentorship accessible and impactful. My technical voice has also been acknowledged by LinkedIn, where I’ve earned the Top Voice badge seven times in domains like web development, programming, and software engineering. In addition, I hold LinkedIn Golden Badges for Research Skills, Interpersonal Skills, Critical Thinking, and Teamwork—signaling a well-rounded approach to both individual contribution and team collaboration. Graduating with an MCA from Chandigarh University in 2023, I’ve continued to fuel my curiosity by writing technical articles and sharing practical MERN stack insights across platforms. Whether it’s building polished UIs, optimizing backend performance, or guiding a mentee through their first pull request, I’m driven by the power of community and continuous learning. Let’s connect! I'm open to collaborations, mentorship, or building something impactful together. Reach out to me at kumaripayal7488@gmail.com or visit my profile on Topmate.io.