1. Single Responsibility
definition: Do not have more than one cause for class changes. In layman's terms, a class is responsible for only one responsibility.
Scenario: 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.
Modify: Follow the principle of single responsibility. 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.
Advantages:
1), can reduce the complexity of the class, a class is only responsible for a responsibility, logic simple;
2), improve the readability of the class, improve the maintainability of the system;
3), the risk of change caused by the reduction, change is inevitable.
2. The principle of substitution on the Richter scale
definition: All references to the base class must be able to use the object of its subclass transparently, that is, the subclass can extend the functionality of the parent class, but not the original function of the parent class
Scenario: 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 sub-class B, while completing the new function P2, may cause the original function P1 to fail.
Modify: 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.
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.
This is the most difficult to understand, usually in the framework of the project to use, for example, the business logic layer is a high-level module relative to the data layer, because the business logic layer needs to call the data layer to connect to the database, but to achieve scalable high-reuse, try not to let the business logic layer depends on the data layer, An interface can be abstracted from the data layer, allowing the business logic layer to rely on this abstract interface.
Scenario: Class A (High-level module) directly depends on class B (Low-layer module), if you want to change class A to rely on Class C (lower module), you must modify the code of Class A to achieve. 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.
The Autosystem class is directly dependent on the Hondacar and Fordcar two classes, resulting in a high coupling, autosystem classes want to manipulate Hondacar or fordcar must create the corresponding object directly.
Modify: 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, such as:
after this modification, Honda and Ford implemented the ICAR interface, providing the run, stop, and turn function methods, Autosystem dependent icar interface, forcing Autosystem to rely on the abstract interface, This allows the Autosystem class to cope with more demand changes.
Advantages:
1), low-level modules as far as possible to have an abstract class or interface, or both.
2), the declaration type of the variable as far as possible is abstract class or interface.
3), the use of inheritance to follow the Richter replacement principle.
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.
Scenario: Class A relies on class B through interface I, Class C through interface I relies on Class D, 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, such as:
Modify: 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:
1), the interface as small as possible, but there must be a limit. The refinement of the interface can improve the design flexibility is not a fact, but if too small, it will result in an excessive number of interfaces, resulting in complex designs. So be sure to be modest.
2), to customize the service for the interface-dependent class, exposes only to the calling class the method it requires, and the method it does not need is hidden. A minimal dependency can be established only by focusing on providing a customized service for a module.
3), improve cohesion, reduce external interaction. Enable the interface to do the most things with the least amount of method.
5. Dimitri rule (least known principle)
Definition: An object should have minimal knowledge of other objects.
Scenario: The closer the relationship between classes and classes, the greater the coupling, and the greater the impact on another class when one class changes.
The simple understanding is cohesion, a class minimizes dependence on other objects, and the methods and properties of this class can be privatized as far as private.
Note:
1), only communicate with the direct friends, do not talk with strangers.
2), excessive use of the principle, will lead to greater complexity of the system. Therefore, in the adoption of Dimitri Law, we should weigh repeatedly, not only to achieve a clear structure, but also high cohesion and low 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.
Scenario: During the software lifecycle, because changes, upgrades, and maintenance are required 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.
Recommendation: When software requirements change, try to implement changes by extending the behavior of the software entities, rather than by modifying existing code.
Six design principles of PHP design pattern