1. Single Responsibility Principle
Definition: Do not have more than one cause of class changes
The origin of the problem: class T is responsible for two different duties: responsibility P1, Responsibility P2. When a class T needs to be modified due to a change in the duty P1 requirements, it is possible to cause a normal function to malfunction P2 functionality.
Solution: Follow a single responsibility principle. Set up two classes T1, T2 respectively, so that T1 complete the functions P1 function, T2 complete functions P2 function. In this way, when the class T1 is modified, the responsibility is not P2 the risk of failure, and similarly, when T2 is modified, the responsibility is not P1 the risk of failure.
Note: To be careful with responsibility diffusion, it is for some reason that responsibility P is divided into finer-grained responsibilities P1 and P2. The actual situation is often more complex, which violates the principle of single responsibility according to business development. Depending on the situation, only logic is simple enough to violate the single responsibility principle at the code level, and only if the number of methods in the class is small enough to violate the single responsibility principle at the method level
2. The Richter replacement principle
Definition: Subclasses can extend the functionality of the parent class, but cannot change the original functionality of the parent class
Problem Origin: There is a functional P1, which is done by Class A. Now need to extend the function P1, the function of the extension is P, where p is composed of the original function P1 and the new function P2. The new function p is done by subclass B of Class A, and subclass B may cause the original function P1 to fail while completing the new function P2
Solution: Follow the Richter substitution principle when using inheritance. When Class B inherits from Class A, try not to rewrite the parent class A's method, but also try not to reload the parent Class A's method, except to add a new method to complete new functionality P2.
Note: If you do not follow this principle, the chances of writing code problems will increase greatly.
3. Dependency Inversion principle
Definition: High-level modules should not be dependent on the lower layers, both should rely on their abstraction; abstractions should not depend on detail; detail should be dependent on abstraction.
The problem is that class A is directly dependent on class B, and if you want to change Class A to dependency Class C, you must modify the code of Class A to achieve it. In this scenario, Class A is typically a high-level module that is responsible for complex business logic, and Class B and Class C are low-layer modules that are responsible for basic atomic operations, and if Class A is modified, it poses unnecessary risks to the program.
Solution: Modify Class A to dependent interface I, Class B and Class C each implement interface I, Class A through interface I indirectly with Class B or Class C, it will greatly reduce the chance to modify Class A.
Note: There are three ways to pass a dependency, the method used in the above example is interface passing, and there are two other ways of passing it: Construction method passing and setter method passing
4. Interface Isolation principle
Definition: The client should not rely on interfaces it does not need, and the dependency of one class on another should be based on the smallest interface.
The problem is that class A relies on class B through interface I, Class C relies on class D through interface I, and if interface I is not the smallest interface for Class A and Class B, then Class B and Class D must implement methods that they do not need.
Solution: Split the bloated interface I into separate interfaces, and Class A and Class C are dependent on the interfaces they need. That is, the principle of interface isolation.
Note: It's a bit like a single responsibility principle, but the point of concern is different. The use of interface isolation principle, must be moderate, the interface design is too large or too small is not good
5. Least known principle (Dimitri Law)
Definition: An object should have minimal knowledge of other objects.
The problem is: the closer the relationship between classes and classes, the greater the coupling, and the greater the impact on another class when one class changes.
Solution: Minimize the coupling between classes and classes.
Supplementary note: Only communicate with direct friends, we call the member variables, method parameters, method return value of the class as a direct friend, and the class that appears in the local variable is not a direct friend. Code that is not related to this class, does not appear in this class, but is encapsulated in other classes, reducing coupling.
6. Opening and closing principle
Definition: A software entity such as classes, modules, and functions should be open to extensions and closed for modification.
The problem is: During the software lifecycle, because changes, upgrades, and maintenance are needed to modify the software's original code, errors may be introduced into the old code, or we will have to refactor the entire functionality and require the original code to be re-tested.
Solution: When the software needs to change, try to implement changes by extending the behavior of the software entities, rather than by modifying existing code.
Add-On: Build the framework with abstraction, with the implementation of extension details. The open and closed principle is the master of the preceding 5 principles. Use good design mode, is to put these 6 principles, according to the actual situation control in a reasonable range, over-design or inadequate design, are the need to reconstruct the design.
Six Principles of design pattern