LSP (The Liskov Substitution Principle)
A subtype must be able to replace its parent type.
Derived classes must be substitutable for their base classes.
The following substitution property is required: if for every object o1 of type S, there exists an object O2 of type T, such that in all programs P programmed for T, the behavior of the program P remains unchanged after o2 is replaced by o1, then S is a subtype of T.
In layman’s terms, this means that a subtype must be able to replace its parent (base type).
- If you find any code that does runtime type recognition, you need to think about whether it violates the Richter substitution rule.
typeof(baseClass) == AClass
- Defines an interface whose behavior cannot be implemented by a subclass. This results in an error in the execution logic, which also violates the Richter substitution principle. The DETERMINATION of IS-A IS based on behavior
Interface Segregation Principle: ISP
Users should not be forced to rely on methods they do not use.
No client should be forced to depend on methods it does not use.
DIP (The Dependency Inversion Principle)
High-level modules should not depend on low-level modules; both should depend on abstractions.
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details; details should depend on abstractions.
Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
All problems in computer science can be solved by introducing a layer of indirection. All problems in computer science can be solved by another level of indirection — David Wheeler
High-level modules do not depend on low-level modules and can be decoupled by introducing an abstraction, or model. High-level modules depend on this model, and low-level modules implement this model.
DIP, IoC, DI
When it comes to DI, we have to mention IoC. Many people confuse DI with IoC, but in fact, the two are related to concept and implementation. There is also a figurative term for DIP, called the Hollywood rule: “Don’t call us, we’ll call you.” In the design, the translation should be “don’t call me, I’ll call you”. Obviously, this is a framework thing to say, given a stable abstraction, various concrete implementations should be invoked by the framework.
The dependency Inversion principle (DIP) : a software design principle that relies on abstraction rather than implementation. IoC: Inverse of Control: A mode that implements the DIP principle. DI: Dependency Injection: a concrete implementation of IoC.
.NET DI framework Autofac
Benefits of introducing a DI framework
- The lifecycle of all components and objects is handled by the container. Can solve and discover complex dependencies, such as circular dependencies
- High-level modules and low-level modules depend on interfaces. For later changes, such as replacing mysql with Cassandra, we only need to implement a set of Cassandra service interfaces and replace mysql in container registration.
- It is much easier to write unit tests when all module dependencies are interfaces, and we can Mock out the components that we depend on through the Mock framework. It’s hard to write tests if you rely on instances.