SOLID Principles in Java

 

🌟 SOLID Principles in Java (OOP Best Practices)

SOLID is an acronym that stands for:

  1. S – Single Responsibility Principle (SRP)

  2. O – Open/Closed Principle (OCP)

  3. L – Liskov Substitution Principle (LSP)

  4. I – Interface Segregation Principle (ISP)

  5. D – Dependency Inversion Principle (DIP)


1️⃣ Single Responsibility Principle (SRP)

A class should have only one reason to change.

💡 Meaning:
Each class should do one thing and do it well. It should have only one responsibility or job.

✅ Benefits:

  • Easier to maintain and test

  • Encourages modular design

🧱 Example (Violation):

class Report {
public void generateReport() { } public void saveToFile() { } // I/O responsibility mixed in }

✅ Correct Design:


class ReportGenerator { public void generateReport() { } } class ReportSaver { public void saveToFile() { } }

2️⃣ Open/Closed Principle (OCP)

Software entities should be open for extension but closed for modification.

💡 Meaning:
You should be able to add new functionality without changing existing code.

✅ Benefits:

  • Avoids breaking existing code

  • Encourages plugin-like behavior

🧱 Example Using Polymorphism:


abstract class Shape { abstract double area(); } class Circle extends Shape { double radius; Circle(double r) { radius = r; } double area() { return Math.PI * radius * radius; } } class Square extends Shape { double side; Square(double s) { side = s; } double area() { return side * side; } } // Add new shapes without modifying existing code

3️⃣ Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their base types without altering the correctness of the program.

💡 Meaning:
If class B is a subclass of A, then we should be able to use B wherever A is expected without unexpected behavior.

❌ Violation Example:


class Bird { void fly() { } } class Ostrich extends Bird { void fly() { throw new UnsupportedOperationException(); } // Ostrich can't fly! }

✅ Better Design:


class Bird { } class FlyingBird extends Bird { void fly() { } } class Ostrich extends Bird { } class Sparrow extends FlyingBird { void fly() { System.out.println("Flying"); } }

4️⃣ Interface Segregation Principle (ISP)

Clients should not be forced to depend on interfaces they do not use.

💡 Meaning:
Use many small, specific interfaces instead of one large, general-purpose interface.

❌ Violation:


interface Worker { void work(); void eat(); // Not all workers eat (e.g., robots) }

✅ Correct Design:


interface Workable { void work(); } interface Eatable { void eat(); }

5️⃣ Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions.

💡 Meaning:
Classes should depend on interfaces or abstract classes, not concrete implementations.

❌ Violation:


class Keyboard { } class Monitor { } class Computer { private Keyboard keyboard = new Keyboard(); private Monitor monitor = new Monitor(); }

✅ Correct Design (using abstraction):


interface Device { } class Keyboard implements Device { } class Monitor implements Device { } class Computer { private Device inputDevice; private Device outputDevice; public Computer(Device input, Device output) { this.inputDevice = input; this.outputDevice = output; } }

🔄 Summary Table

PrincipleDefinitionGoal
SRP    One class = one responsibility        Maintainability
OCP        Extend, don’t modify existing code        Scalability
LSP    Subtypes replace base types safely        Robustness
ISP    Use specific interfaces        Flexibility
DIP        Depend on abstractions, not concretes        Loose Coupling

Comments

Popular posts from this blog

Object Oriented Programming PBCST304 KTU BTech CS Semester 3 2024 Scheme - Dr Binu V P

Introduction to Java Programming

Inheritance and Polymorphism