30-July 2024
Training

Solid Principles Java

..
Solid Principles Java

 

SOLID Principles Java with Explanation

SOLID principles are a set of design principles in object-oriented programming that help developers create more understandable, flexible, and maintainable software. They were introduced by Robert C. Martin and stand for:

  1. Single Responsibility Principle (SRP)

  2. Open/Closed Principle (OCP)

  3. Liskov Substitution Principle (LSP)

  4. Interface Segregation Principle (ISP)

  5. Dependency Inversion Principle (DIP)

1. Single Responsibility Principle (SRP)

Definition: A class should have only one reason to change, meaning it should have only one job or responsibility. Example in Java:

 

class Book {

    private String title;

    private String author;

 

    // Constructor, getters, and setters

 

    public String getTitle() {

        return title;

    }

 

    public String getAuthor() {

        return author;

    }

}

 

class BookPrinter {

    public void print(Book book) {

        System.out.println(book.getTitle() + " by " + book.getAuthor());

    }

}

In this example, the Book class is responsible for storing book data, while the BookPrinter class handles printing the book details, adhering to SRP.

 

2. Open/Closed Principle (OCP)

Definition: Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. Example in Java:

abstract class Shape {

    abstract void draw();

}

 

class Circle extends Shape {

    void draw() {

        System.out.println("Drawing a Circle");

    }

}

 

class Square extends Shape {

    void draw() {

        System.out.println("Drawing a Square");

    }

}

 

class Drawing {

    public void drawShape(Shape shape) {

        shape.draw();

    }

}

In this example, new shapes can be added by extending the Shape class without modifying the existing code.

 

3. Liskov Substitution Principle (LSP)

Definition: Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program. Example in Java:

class Bird {

    public void fly() {

        System.out.println("Flying");

    }

}

 

class Sparrow extends Bird {

    // Inherits fly() method

}

 

class Ostrich extends Bird {

    // Ostrich cannot fly, so it violates LSP if fly() is called on an Ostrich instance

}

To adhere to LSP, you might need to redesign the hierarchy:

abstract class Bird {

    // No fly method

}

 

class FlyingBird extends Bird {

    public void fly() {

        System.out.println("Flying");

    }

}

 

class Sparrow extends FlyingBird {

    // Inherits fly() method

}

 

class Ostrich extends Bird {

    // Does not have fly() method

}

 

4. Interface Segregation Principle (ISP)

Definition: Clients should not be forced to depend on interfaces they do not use. Example in Java:

interface Worker {

    void work();

    void eat();

}

 

class WorkerImpl implements Worker {

    public void work() {

        System.out.println("Working");

    }

 

    public void eat() {

        System.out.println("Eating");

    }

}

 

class Robot implements Worker {

    public void work() {

        System.out.println("Working");

    }

 

    public void eat() {

        // Robots do not eat, violates ISP

    }

}

To adhere to ISP:

interface Workable {

    void work();

}

 

interface Eatable {

    void eat();

}

 

class Worker implements Workable, Eatable {

    public void work() {

        System.out.println("Working");

    }

 

    public void eat() {

        System.out.println("Eating");

    }

}

 

class Robot implements Workable {

    public void work() {

        System.out.println("Working");

    }

}

5. Dependency Inversion Principle (DIP)

Definition: High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details should depend on abstractions. Example in Java:

class Light {

    public void turnOn() {

        System.out.println("Light is on");

    }

 

    public void turnOff() {

        System.out.println("Light is off");

    }

}

 

class Switch {

    private Light light;

 

    public Switch(Light light) {

        this.light = light;

    }

 

    public void operate() {

        light.turnOn();

    }

}

To adhere to DIP:

interface Switchable {

    void turnOn();

    void turnOff();

}

 

class Light implements Switchable {

    public void turnOn() {

        System.out.println("Light is on");

    }

 

    public void turnOff() {

        System.out.println("Light is off");

    }

}

 

class Switch {

    private Switchable device;

 

    public Switch(Switchable device) {

        this.device = device;

    }

 

    public void operate() {

        device.turnOn();

    }

}

These principles help in designing a system that is easier to manage and extend over time.

 

Leave a comment

Your email address will not be published. Required fields are marked *