codeWithYoha logo
Code with Yoha
Clean code

Solid principles Guide

Solid principles Guide
0 views
4 min read
#Clean code

Software development principles are essential for writing clean, maintainable, and scalable code. One such set of principles is the SOLID principles, which provide guidelines for designing software that is easy to understand, flexible, and reusable. While these principles were first introduced by Robert C. Martin in the early 2000s, they are still highly relevant in today's software industry.

The SOLID principles are a set of five design principles that help developers create software that is easy to understand, maintain, and modify. Each principle focuses on a specific aspect of software design and together they form a guide for building robust and scalable applications.

Single Responsibility Principle (SRP)

This principle states that a class should have only one reason to change. In other words, a class should have only one responsibility or purpose.

// Not following SRP
class Employee {
    void calculateSalary() { /* ... */ }
    void generateReport() { /* ... */ }
}

// Following SRP
class Employee {
    void calculateSalary() { /* ... */ }
}

class ReportGenerator {
    void generateReport(Employee employee) { /* ... */ }
}

Open-Closed Principle (OCP)

This principle states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that new functionality should be added by extending existing code rather than modifying it.

// Not following OCP
class Rectangle {
    int width, height;
}

class AreaCalculator {
    double calculateRectangleArea(Rectangle rectangle) {
        return rectangle.width * rectangle.height;
    }
}

// Following OCP
interface Shape {
    double calculateArea();
}

class Rectangle implements Shape {
    int width, height;

    @Override
    public double calculateArea() {
        return width * height;
    }
}

Liskov Substitution Principle (LSP)

This principle defines that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program.

// Not following LSP
class Bird {
    void fly() { /* ... */ }
}

class Penguin extends Bird {
    void fly() {
        // Penguins can't fly, so this method is misleading.
    }
}

// Following LSP
interface Bird {
    void move();
}

class Sparrow implements Bird {
    void move() {
        // Implementation for flying
    }
}

class Penguin implements Bird {
    void move() {
        // Implementation for swimming
    }
}

Interface Segregation Principle (ISP)

According to this principle, clients should not be forced to depend on interfaces they do not use. It promotes the idea of having smaller, more specific interfaces rather than a single large interface.

// Not following ISP
interface Worker {
    void work();
    void eat();
}

class Robot implements Worker {
    void work() { /* ... */ }
    void eat() { /* ... */ }
}

// Following ISP
interface Workable {
    void work();
}

interface Feedable {
    void eat();
}

class Robot implements Workable {
    void work() { /* ... */ }
}

Dependency Inversion Principle (DIP)

This principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions. In other words, instead of depending on concrete implementations, code should depend on abstractions or interfaces.

// Not following DIP
class LightBulb {
    void turnOn() { /* ... */ }
    void turnOff() { /* ... */ }
}

class Switch {
    LightBulb bulb;

    Switch(LightBulb bulb) {
        this.bulb = bulb;
    }

    void operate() {
        // Operate the light bulb
    }
}

// Following DIP
interface Switchable {
    void turnOn();
    void turnOff();
}

class LightBulb implements Switchable {
    void turnOn() { /* ... */ }
    void turnOff() { /* ... */ }
}

class Switch {
    Switchable device;

    Switch(Switchable device) {
        this.device = device;
    }

    void operate() {
        // Operate the device
    }
}

In summary, SOLID principles are invaluable guidelines for software developers that result in code that is modular, testable, flexible, scalable, and maintainable. Applying these principles brings a wide range of benefits, such as improved code quality, increased productivity, easier debugging, and enhanced collaboration among developers.

That's all for this tutorial, I hope you enjoyed it, and until our next tutorial, take care.
Thank you!