PHP design patterns-six principles
Code that follows the following six principles is generally considered to be easily scalable and reusable:
These six principles should be followed by any object-oriented language. If you want to make your code easy to expand and take high, try to satisfy these six principles. It is not necessarily based on a certain design model, however, if your code meets these six principles, your code is good code, and good code is not necessarily written in strict accordance with the design pattern.
1. Single responsibility
Definition: there should be no more reasons for class changes. In general, a class is only responsible for one responsibility.
Scenario: Class T has two different responsibilities: Responsibility P1 and responsibility P2. When the class T needs to be modified because of the change in the responsibility P1 requirement, it may lead to the failure of the originally running responsibility P2 function. The relationship is as follows:
Modify: Follow the single responsibility principle. Create two classes T1 and T2 respectively, so that T1 completes the responsibility P1 function, and T2 completes the responsibility P2 function. In this way, when the class T1 is modified, the responsibility P2 will not be at risk of failure. Similarly, when the class T2 is modified, the responsibility P1 will not be at risk of failure. The structure is as follows:
Advantages:
1) The complexity of a class can be reduced. A class is only responsible for one responsibility, and the logic is simple;
2) improve readability and maintainability of the system;
3) the risks caused by changes are reduced, and changes are inevitable.
2. Lee's replacement principle
Definition: all objects that reference the base class must be transparently used. That is to say, the subclass can extend the function of the parent class, but cannot change the original function of the parent class.
Scenario: There is A function P1, which is completed by Class. Now you need to extend the feature P1. The extended feature is P, where P is composed of the original feature P1 and the new feature P2. New function p is completed by subclass B of Class A. When new function P2 is completed, subclass B may fail the original function P1, for example:
The CountPriceByJKL class inherits from the CountPrice class. CountPriceByJKL overwrites the Count () method, which may affect the functions of the original Count method.
Modify: When inheritance is used, follow the principle of RYS replacement. When Class B inherits Class A, in addition to adding A new method to complete the new function P2, try not to override the method of parent class A, and try not to reload the method of parent Class.
3. Dependency inversion principle
Definition: High-Level modules should not depend on low-level modules, both of which should depend on their abstraction; abstraction should not rely on details; details should rely on abstraction.
This is the most difficult to understand. It is generally used when a project framework is built. 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 high scalability and reuse, try not to make the business logic layer dependent on the data layer. You can abstract an interface at the data layer, make the business logic layer dependent on this abstract interface.
Scenario: Class A (high-level module) directly depends on Class B (low-level Module). If you want to change Class A to dependent class C (low-level module ), you must modify the code of Class. In this scenario, Class A is generally A high-level module responsible for complex business logic; class B and class C are low-level modules responsible for basic atomic operations; if Class A is modified, it brings unnecessary risks to the program.
The AutoSystem class directly depends on the HondaCar and FordCar classes, which produces a high coupling. To control the HondaCar or FordCar class, you must directly create the corresponding object.
Modify: Change Class A to dependent interface I. class B and class C implement interface I. Class A indirectly associates with Class B or Class C through interface I, this greatly reduces the chance of modifying Class A, for example:
After this modification, Honda and Ford implemented the ICar interface and provided the Run, Stop, and Turn functions. AutoSystem relied on the ICar interface, which forced AutoSystem to rely on the abstract interface, this enables the AutoSystem class to respond to more demand changes.
Advantages:
1) low-level modules should have abstract classes or interfaces, or both.
2) The declaration type of variables should be abstract classes or interfaces.
3) Use inheritance follows the Lee's replacement principle.
4. Interface isolation principle
Definition: the client should not depend on the interface it does not need; the dependency of one class on another class should be built on the smallest interface.
Scenario: Class A depends on Class B through interface I, and class C relies on Class D through interface I. If interface I is not the smallest interface for Class A and Class B, then class B and class D must implement the methods they do not need, such:
Modify: Split bloated interface I into several independent interfaces. Class A and Class C establish dependencies with the interfaces they need. That is, the interface isolation principle is adopted.
Note:
1) the interface should be as small as possible, but limited. Refining the interface can improve the flexibility of the program design. However, if it is too small, it will cause too many interfaces and complicate the design. So be sure to make it moderate.
2) create a service for the class that depends on the interface, only expose the method required by the called class, and hide the method that is not needed. Only by providing customized services for a module can the minimum dependency be established.
3) improve cohesion and reduce external interactions. Make the interface do the most things in the least way.
5. The dimit Law (least aware principle)
Definition: an object should have a minimum understanding of other objects.
Scenario: The closer the relationship between classes, the greater the coupling degree. When a class changes, the greater the impact on the other class.
A simple understanding is high cohesion. The methods and attributes of a class can be private as much as possible.
Note:
1) only communicate with direct friends and do not speak with strangers.
2) excessive use of this principle will increase the complexity of the system. Therefore, when using the Demeter rule, we must weigh it repeatedly to ensure a clear structure and high cohesion and low coupling.
6. Open and Close principles
Definition: A software entity, such as a class, module, or function, should be open to extensions and closed to modifications.
Scenario: During the software life cycle, errors may be introduced to the Old Code when the original code of the software needs to be modified due to changes, upgrades, maintenance, and other reasons, it may also cause us to have to refactor the entire function and re-test the original code.
Suggestion: when the software requirement changes, try to implement changes by extending the behavior of the software entity, rather than modifying the existing code.