What is SOLID design principles

SOLID principles form the fundamental design guidelines for Object Oriented Programming. Understanding these principles are important to make the application scalable as well as maintainable.

When the application scope increases and new features are added, bad design can make the task very difficult while a well designed application can reduce the effort significantly and also make it bug free.

Now lets understand each of the element of S.O.L.I.D principles. The five principles which it represent is

  • (S) Single Responsibility Principle: It means one class should have only one and only responsibility.
  • (O) Open Closed Principle:  Software components should be open for extension, but closed for modification.
  • (L) Liskov’s Substitution Principle: Derived types must be completely substitutable for their base types.
  • (I) Interface Segregation Principle: Clients should not be forced to implement unnecessary methods which they will not use.
  • (D) Dependency Inversion Principle: Depends on abstractions not on concretions.

Lets discuss each in detail.

  1. Single Responsibility Principle:
“One class should have one and only one responsibility” 
What it means is a class should be written or modified for a single reason.
It doesn't mean that the class will have a single method. It can have multiple methods but the methods should be related and align to a single responsibility. This concept can further be extended to microservices as well. A microservice should be written in a way that it is responsible for a single purpose like Login Microservice.

Now lets understand with an example.
Suppose we have an EmployeeService class to implement some operations on employee object. Operations can be add, modify or delete employee from the system.

public class EmployeeService() {
   private void addEmployee(Employee employee){
      try{
          db.add(employee);
       }
       catch (Exception ex)
       {
         db.logError("Add operation Failed: ", ex.ToString());
         File.writeErrorText("Error.txt", ex.ToString());
        } 
    }
}

Above implementation is a bad code as it violates single responsibility principle. Along with adding employee operation it is implementing logging operation as well in the same class. Instead of doing this way a separate LoggerService class should be created to implement logging functionality which can be called from this method.

 public class EmployeeService() {
   private LoggerService logger = new  LoggerService(); 
   private void addEmployee(Employee employee){
      try{
          db.add(employee);
       }
       catch (Exception ex)
       {
         logger.logError(ex.toString());
        } 
    }
} 

 public class LoggerService() { 
    private void logError(String errorMsg){ 
       db.logError("Add operation Failed: ",  errorMsg );
       File.writeErrorText("Error.txt",  errorMsg); 
    }
 }

Benefit of Using this principle

  1. Testing is Easier
  2. Organised Code
  3. Loosely Coupled

2. Open Closed Principle

"open for extension, but closed for modification". 
This principle dictates that a class should be constructed in a way that it is complete in itself and does not required to be changed every time a specific scenario is added. So if some class is written and in future someone is not able to add a new behaviour to the class without changing the existing flow, then the class should be redesigned.

Lets take an example to understand better:


3. Liskov’s Substitution Principle:

"Derived types must be completely substitutable for their base types".
To simplify it means the subclasses  should behave similar behaviour to its parents class so that the application doesn't disrupt if we replace base class with subclass in future.

Leave a Comment

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