SOLID IntroductionSingle responsibility principleOpen–closed principleLiskov substitution principleInterface segregation principleDependency inversion principle Single responsibility principle Open–closed principle Liskov substitution principle Interface segregation principle Dependency inversion principle

In object-oriented computer programming, SOLID is acronym for five design principles intenndes to make software designs more understandable, flexible and maintainable.

Single responsibility principle

It states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and will have only one reason for modification. We can test the class independently. When we add some more functionality the old tests shouldn’t fail.

Open–closed principle

The open/closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. This can be achieved by abstraction and polymorphism.

Open Close Before

Open Close After

Liskov substitution principle

It states that if S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of the program. The test for parent class should also be availible for the derived.

Liskov Substitution

Interface segregation principle

It states that no client should be forced to depend on methods it does not use, we should split interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Keep test sinple for each interface.

Dependency inversion principle

The dependency inversion principle is a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions(interfaces).
  2. Abstractions should not depend on details. Details (classes) should depend on abstractions.

The both high-level and low-level objects must depend on the same abstraction. The interaction between a high level module and a low-level one, the interaction should be thought of as an abstract interaction between them.

The high-level class defines its own adapter interface which is the abstraction that the other high-level classes depend on. The adaptee implementation also depends on the adapter interface abstraction while it can be implemented by using code from within its own low-level module. The high-level has no dependency on the low-level module since it only uses the low-level indirectly through the adapter interface by invoking polymorphic methods to the interface which are implemented by the adaptee and its low-level module, for example plugin.

More easy to do testing, we can inject mock dependencies fairly easy.