DEV Community

Abhishek Adhav
Abhishek Adhav

Posted on

SOLID Principle

What are SOLID Principle

  • The SOLID principles are design principles aimed at creating more understandable, flexible, and maintainable software. These principles can help improve the design of the application and improving the structure of an software applications.

  • Following are the five SOLID principle.

  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) We will understand all of this in detail.

Single Responsibility Principle (SRP)
Definition :- Every class should have only one reason to change.

SRP suggest that one class should have only one responsibility means every class, module, or function in a program should have one responsibility/purpose in a program.

Image description

Above code snippet violate the SRP principle StudentRegistration have two responsibility.

We can fix this by separating the logic for RegisterStudent and Calculate_Student_Result in different class.

Image description

Merits of SRP:

  • Improved maintainability and easier testing due to focused, single-responsibility classes.

Demerits of SRP:

  • Can lead to over-engineering with an increased number of classes and added complexity for simple applications.

Open/Closed Principle (OCP)

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

OCP in simple words say that once created class or function should be closed for further modification means once the class is correctly working no addition logic should be added to the class. But open for extension means one can extend the implementation (of a class or function) of logic and/or functionality by using Inheritance.

Image description

In the above example if we want to add another type of customer we will have to change the class DiscountCalculator. which violate the rule.
This can be resolve by introducing new Interface which will defines a CalculateDiscount method, which each customer class will implement.

Image description

Now in this scenario the DiscountCalculator class will never be modified but will be used for extension .

Merits of Open/Closed Principle:

  • Enhances flexibility by allowing extensions without modifying existing code, promoting maintainability.

Demerits of Open/Closed Principle:

  • Can lead to increased complexity and a larger number of classes due to the need for abstraction and extensions.

Liskov Substitution Principle (LSP)

Definition :- It states that objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.

In other words, subtypes must be substitutable for their base types without altering the desirable properties of the program, such as correctness, behavior, or functionality.

Image description

In the above code the LSP principle is follow as the object of object of Shape can be replaceable by Square class and it not breaking the behavior of the program.

Merits of Liskov Substitution Principle (LSP):

  • Enhances code reusability and maintainability by ensuring subclasses can be substituted for base classes without altering the program’s correctness.

Demerits of Liskov Substitution Principle (LSP):

  • May lead to overly complex hierarchies if not applied carefully, potentially causing confusion or unnecessary abstraction.

Interface Segregation Principle (ISP)

Definition :- The Interface Segregation Principle (ISP) states that clients should not be forced to depend on interfaces they do not use.
In other words, rather than having a large, all-encompassing interface, it's better to break it down into smaller, more specific interfaces. This ensures that a class or client only needs to implement or depend on the methods that are relevant to them.

Image description

Both Engineer and Designer are forced to implement methods that may not be relevant to their job role. For example, a Designer might not need to implement Eat() or Sleep() methods in a real-world scenario, but the large interface forces them to do so.

The solution is to split the large IWorker interface into smaller, more specific interfaces, so each class only implements the methods it truly needs.

Image description

Merits of ISP:

  • Improves maintainability, flexibility, and testability by ensuring classes only depend on the methods they use.

Demerits of ISP:

  • Increases the number of interfaces to manage and may lead to unnecessary abstraction.

Dependency Inversion Principle (DIP)

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

This principle encourages decoupling of high-level logic (business rules) from low-level details (implementation). Instead of the high-level module directly depending on the low-level module, both should depend on abstractions (like interfaces or abstract classes).

Below example show the tight couple of high level module with low-level module

Image description
The NotificationService is directly dependent on EmailService. If we want to change the email implementation (e.g., switch to SMS or push notification), we must modify the NotificationService class, violating the DIP.
Here is a solution

Image description

Now The NotificationService class depends on IMessageService, not on a specific low-level implementation like EmailService. It receives the IMessageService dependency via constructor injection.

Merits of DIP:

  • Improves flexibility, maintainability, and testability by decoupling high-level and low-level modules through abstractions.

Demerits of DIP:

  • Increases complexity due to the need for abstractions and dependency injection.

SO this are the five SOLID principle which is used for clean coding and can be followed in any programming language

Top comments (0)