SOLID is a programming principle associated with object orientation. Therefore it is a rule that is recommended to follow. Some will call it good practice. In fact they are very interesting concepts to learn and to know because they exist, what problems they solve and especially when to use. The worst thing you can do with it is to always use it. The correct one is to use whenever necessary, when it will bring more benefits than harm. SOLID should be a tool, not the goal, as many people do.
It's useful for organizing complex applications that need a lot of maintenance , dealing with a lot of uncertainty and meeting many expectations different .
In general, one only knows when it is useful or not with much experience and deep understanding of everything that surrounds it. As this rarely occurs, people either leave it there altogether or adopt it in everything they do without having a criterion.
Some principles are more important than others. But whoever is very SOLID fan thinks everyone should be used equally.
It is common to see that in order to deal with complexity it makes the code even more complex. Of course there are advantages as well.
It is an acronym of the 5 principles that helps you remember them when you are designing an application.
S ingle responsibility principle
The class should have a unique responsibility, should not do more than necessary. The name must clearly indicate what it does to indicate its unique function. Worth to other entities too
O pen / closed principle
Software entities must be open for extension, but closed for modification. This facilitates maintenance and prevents conflicts between versions
L iskov substitution principle
Objects in the program can be overridden by instances of their subtypes without affecting application consistency, so the subtype can not have activities, either in contract or implementation, that are incompatible with the supertype
I nterface segregation principle
Interfaces should indicate as little as possible instead of doing everything that is possible. More interfaces are better than larger interfaces. It's almost the same thing as the single responsibility applied to the interface
D ependency inversion principle
The code should depend on abstractions, not on concretions. How something works should be defined by the object and not by the contract used. So it is better to use interfaces as parameters and to receive objects that implement it as an argument