Close button

Are You Looking for Developers to Hire?
Have a Look at Our Bench Strength

Hire Developers
Close button
SOLID Principles Every Developer Should Know

SOLID Principles Every Developer Should Know

By Arun Kumar

The SOLID principles every developer should know

SOLID Principles Every Developer Should Know

SOLID principles define the best practices framework that is useful for creating an application or writing code. It helps write efficient, reusable, bug-free code and create an efficient architecture to handle it.

In this article, we will study the SOLID framework and its defined rules that are based on five principles. These 5 principles sum up to form the acronym SOLID. Let's look into each of them.

1. Single Responsibility

SOLID Principles Every Developer Should Know

The single responsibility principle states that a class should have only one responsibility on it. This also implies that it should have only one reason to change. It is quite daunting to understand this. Demonstrating a practical example as below.

A practical example of Single responsibility using a car entity

Below is an example of a car entity that has few fields.

A practical example of Single responsibility using a car entity

For displaying data to the end layer of the application, a method is required which will display the data currently to the console.

For displaying data to the end layer of the application, a method is required which will display the data currently to the console.

For displaying the data other than consoles such as an Excel or text document, there is a need for another method/methods. This would break the single responsibility principle. This is because the class is now responsible for basic operations on the Car entity and printing output in the desired format.

For fixing this problem, there is a need to create another class ‘CarPrinter’. This class would handle all the printing-related responsibility for the Car entity. This demonstrates the single responsibility principle.

2. Open for Extension, Closed for Modification

SOLID Principles Every Developer Should Know

This principle states that any class should be always open for extension and should be closed for further modification. This implies that any new functionality should be added as an extension for a class and the original class should not be modified. This ensures that no new bugs are introduced to the existing functionality.

Adding a feature maxNitroSpeed for racing cars, which is a derived entity from previous car entity. Rather than modifying the existing car code, a new class called RacingCar is created. This class will extend the base Car class and will have the extra features it needs.

A practical example of the OPEN/CLOSED principle using a car entity

A practical example of the OPEN/CLOSED principle using a car entity

The existing functionality of the Car class is not affected. Thus, no new bugs related to Car would occur due to the new change in feature addition of the RacingCar entity.

3. Liskov Substitution

SOLID Principles Every Developer Should Know

This principle states that if class A is a subtype of class B, then A should be able to replace B without any disruptions in the program. To understand the idea of the Liskov substitution, interface Bird is created below. The interface has 2 methods: fly and walk. There is a pigeon entity that implements the bird interface.

Understanding Liskov substitution using a bird entity and interface

Understanding Liskov substitution using a bird entity and interface

After the addition of the pigeon entity, 1 more entity is to be added called penguin which falls under the criteria of bird entity. The problem with this approach is penguins can’t fly. This would lead to an error in the fly method which is wrong. As class Penguin now cannot replace Bird which violates the Liskov substitution principle.

Separate interfaces are needed for FlyingBirds and NonFlying Birds. Pigeons can implement FlyingBird and Penguins can implement NonFlyingBird.

Separate interfaces are needed for FlyingBirds and NonFlying Birds. Pigeons can implement FlyingBird and Penguins can implement NonFlyingBird.

As seen above, the correct allocation of interfaces to respective entities is done. Penguins can replace nonFlyingBird and pigeons can replace FlyingBird. This behavior is in line with the Liskov substitution principle.

4. Interface Segregation

SOLID Principles Every Developer Should Know

This principle states that any larger interface should be split into multiple smaller interfaces. By doing this, the classes implementing them are just concerned with the methods they are interested in. For understanding the segregation of interfaces, an interface FeedAnimals is shown. This interface takes care of feeding animals.

Demonstration of Interface segregation using an animals interface and entity

Demonstration of Interface segregation using an animals interface and entity

There are 2 methods called feedElephants and feedLions. Considering feeding a lion is a dangerous task, only an experienced person should be allowed to feed a lion. Following the previous statement, 2 interfaces are created out of the FeedAnimals interface as below:

There are 2 methods called feedElephants and feedLions. Considering feeding a lion is a dangerous task, only an experienced person should be allowed to feed a lion.

After the segregation of interfaces, the experienced person can feed the lion and the naive person can feed the elephant.

5. Dependency Inversion

This principle implies that there should be decoupling between modules of an application. High-level modules and low-level modules should depend on abstractions. High-level modules should not depend on low-level modules. Below is the practical use case of the dependency inversion principle. The example is continued from the previous Car entity.

Understanding Dependency Inversion using a car entity with an added feature

The car entity below is a modified version of the base car entity. An attribute model is added to the entity which defines the model of a car.

Understanding Dependency Inversion using a car entity with an added feature

Currently models are initialized as BMWModel when Car entity is instantiated. This in turn takes away the ability to use any other car model by tightly coupling the Model with Car. Thus, Model and Car need to be decoupled for the dependency inversion principle to be applied.

Currently models are initialized as BMWModel when Car entity is instantiated. This in turn takes away the ability to use any other car model by tightly coupling the Model with Car.

After the changes, Car entity can now accept different models and is decoupled from the Model class

Key takeaway

The SOLID principles state very fascinating and important rules that bring immense benefits to your code. Here are some to list down a few:

  • Testing becomes easy due to the single responsibility principle.
  • No new bugs will be introduced in the old system due to new modifications that come with the open/closed principle.
  • Organized code that’s easy to read.
  • The interfaces will be well defined with their responsibility. The classes implementing them would have a cleaner implementation. This would be due to Interface segregation and Liskov substitution.

Overall, these principles define the quality of code and design of any application. Every developer should be aware of it and should implement it.