Each of the SOLID Principles Explained in Less Than 20 Seconds
S.O.L.I.D. is the acronym for a set of five O.O.P. design principles that will help you avoid writing fragile, rigid, or non-reusable software.
In this article, we’ll briefly describe each of them and we’ll see how they can help us control the dependency structure of our application.
1. Single Responsibility Principle
The Single Responsibility Principle states that classes or components should have a single source of change.
For instance, if a business use case regarding payments changes, only the functions from the dedicated component should be affected. If any other component or module needs changes, they do not conform to the Single Responsibility Principle.

2. Open/Closed Principle
According to the Open/Closed Principle, a class or component should be opened for extension and closed for change.
If we follow this principle, we should be able to add a new feature just by extending the component — without touching any of the existing code.
Have you ever noticed how senior developers refactor the existing code before adding a new feature? Initially, they make sure the code conforms to the Open/Closed Principle. After that, they add the new feature without further touching the old code.

3. Liskov Substitution Principle
Liskov Substitution Principle states that a derived class should be able to substitute its parent without the client knowing.
For example, if our function returns a List we have the freedom of changing it internally from a LinkedList to a HashList without breaking the code that’s using it.
On the other hand, if we extend a base class and our implementation will return a different result or cause unexpected side effects, this would be a violation of Liskov’s Substitution Principle.

4. Interface Segregation Principle
To conform to the Interface Segregation Principle, a client should never depend on functions that it’s not going to use.
Let’s assume we have an interface with the methods a(…), b(…), and c(…). If there are clients only using the methods a(…) and b(…), we are violating the Interface Segregation Principle. A solution would be to break the existing interface into smaller ones.
Moreover, suppose we implement this interface and do provide implementations for a(…) and b(…) but not for c(…), it means, yet again, that there will be clients not using c(...) — therefore we are violating the principle.
5. Dependency Inversion Principle
According to the Dependency Inversion Principle, high-level modules should not depend on low-level modules. Details should depend upon abstractions.
For instance, we can imagine having a payment module and various classes for concrete payment implementations. The various implementations should depend upon the payment module to conform to the Dependency Inversion Principle.
As a result, a change in one of the concrete payment implementations (the “details”), won’t affect the high-level payment module (or any other component).

Conclusion
In this article, we briefly described each of the five SOLID principles.
The SOLID principles teach us how to build classes that are not rigid, fragile, or non-reusable.
If we look at the bigger picture, these concepts will be used when designing the components or modules of our system. If you want to dive deeper into this subject, read the article about Component Cohesion Principles — they are the “older brothers” of SOLID.
On the other hand, if you want to learn more about SOLId, I highly recommend watching this talk by Uncle Bob.
After a fairly long introduction, he is explaining what an O.O.P. language is and how encapsulation, inheritance, and polymorphism work.
After that, he shows how to use the SOLID principles to get control over the dependency structure of your system and why this is important.
