DEV Community

Subhash Jha
Subhash Jha

Posted on

SOLID Principles

The principles :

  • Single-responsibility principle
  • Open-Closed principle
  • Liskov substitution principle
  • Interface segregation principle
  • Dependency inversion principle

Single Responsibility Principle

A class should do one thing and therefore it should have only a single reason to change

class Vehicle {
    public:
    int speed;
    Engine* engine;
    int mileage;
    void changeSpeed();
    void changeDirection();
    void repair();            // Violate SRP
}

// FIX
class Garage {
    public:
    void repair(Vehicle* vehicle);
}
Enter fullscreen mode Exit fullscreen mode

Open Closed Principle

Classes should be open for extension and closed to modification.

class Garage {
    public:
    void repairLocal(Vehicle* vehicle);
    void repairBranded(Vehicle* vehicle); // Violate Open closed principle
}
// Addition of new tyep of repair will result into modfying the existing class.

//FIX
class Garage {
    public:
    virtual void rapair(Vehicle* vehicle) = 0;
}

class LocalGarage : public Garage {
    public:
    void repair(Vehicle* vehicle);  //Local repair
}

class BrandedGarage : public Garage {
    public:
    void repair(Vehicle* vehicle);  //Branded repair
}

Enter fullscreen mode Exit fullscreen mode

Liskov Substitution Principle

Subclasses should be substitutable for their base classes

Liskov Substitution Principle is an extension of the Open Close Principle and is violated when you have written code that throws “not implemented exceptions” or you hide methods in a derived class that have been marked as virtual in the base class.

class Vehicle {
    public:
    virtual void changeGear();
}

class Scooti : public Vehicle {
    public:
    void changeGear(){
        throw("Not implemented"); //Violate Liskov substitution principle
    }
}

// FIX
class Vehicle {
}

class GearVehicle : public Vehicle {
    public:
    virtual void changeGear();
}

class NonGearVehicle : public Vehicle {
}

class Scooti : public NonGearVehicle {
}
Enter fullscreen mode Exit fullscreen mode

Interface Segregation Principle

Separating the interfaces

The principle states that many client-specific interfaces are better than one general-purpose interface. Clients should not be forced to implement a function they do no need.

// FIX
class Vehicle { // Common Base Interface
}

class GearVehicle : public Vehicle { // Segregated Interface 1
    public:
    virtual void changeGear();
}

class NonGearVehicle : public Vehicle { // Segregated Interface 1
}

class Scooti : public NonGearVehicle { // Implement only what required
}
Enter fullscreen mode Exit fullscreen mode

LSP vs ISP

LSP: The receiver must honor the contracts it promises.
ISP: The caller shouldn’t depend on more of the receiver’s interface than it needs.
Where they fit: If you apply the ISP, you use only a slice of the receiver’s full interface. But according to LSP, the receiver must still honor that slice. If you fail to apply ISP, there can be a temptation to violate LSP. Because “this method doesn’t matter, it won’t actually be called.”

Liskov Substitution addresses Subtypes design whereas Interface Segregation addresses Basetypes design.




Dependency Inversion Principle

Our classes should depend upon interfaces or abstract classes instead of concrete classes and functions

class Vehicle {
}

class Car : public Vehicle {
}

class Garage {
public:
    void repair(Vehicle* vehicle); // depends on Vehicle interface rather then on Car
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)