In object-oriented design, how to deal with changes in design requirements through small changes is a matter of great concern to designers. To this end, many oo pioneers have proposed many object-oriented design principles to guide the design and development of OO. Below are several design principles related to class design.
1. The open closed principle OCP)
A module should be open in terms of scalability and closed in terms of modification. Therefore, the interface encapsulation mechanism, abstract mechanism, and polymorphism technology should be considered in object-oriented design. This principle is also suitable for non-object-oriented design, and is one of the important principles of software engineering design methods.
Let's take the radio as an example to describe the object-oriented open and closed principle. When we listen to the program, we need to turn on the radio power to align the radio frequency and adjust the volume. However, for different radios, the details of the three steps are often different. For example, the Operation Details of auto-shrinking radio stations are not the same as those of the pay-as-you-go radio station. Therefore, we are unlikely to implement (reload) these different operations for different types of radios through a radio class. However, we can define a radio interface that provides six Abstract METHODS: boot, shutdown, increase frequency, decrease frequency, increase volume, and decrease volume. Different radios inherit and implement these six abstract methods. In this way, the new radio type does not affect other original radio types, and the radio type extension is extremely convenient. In addition, the existing radio type does not affect other types of radios when you modify the operation method.
Figure 1 is an example of a radio diagram generated by the application OCP:
Figure 1 OCP application (Radio)
2. replacement principle (the liskov substitution principle LSP)
Subclass should be able to replace the parent class and appear anywhere the parent class can appear. This principle is the design principle proposed by liskov in 1987. It can also be introduced from the design by contract concept of Bertrand Meyer.
Take the students as an example. The night students are child classes of the students, so they can appear anywhere they can. This example is somewhat far-fetched. In an example that can reflect this principle, the circle is a special subclass of the elliptical. Therefore, the circle can appear in any place where an ellipse occurs. But in turn, it may not work.
The following figure shows the related diagram of liskov:
Figure 2 liskov principles
When using the replacement principle, we try to design class B as an abstract class or interface so that class C inherits Class B (interface B) and implements operations A and B, class C instance replaces B, so that we can extend the new class (inheriting Class B or interface B) without modifying Class.
3. The dependency inversion principle dip)
During business design, dependencies related to specific businesses should be dependent on interfaces and abstract classes as much as possible, rather than specific classes. A specific category is only responsible for the implementation of the relevant business. modifying a specific category does not affect the dependencies related to the specific business.
In the structural design, we can see that the underlying module implements the high-level abstraction module (the high-level abstraction module calls the underlying module, abstract modules depend on specific implementation modules. Changes to the specific implementation of the underlying modules will seriously affect the high-level abstract modules. This is obviously a "hard nut to crack" of the structured method ".
The dependency between object-oriented methods is the opposite. The specific implementation classes depend on abstract classes and interfaces (see figure-3 ).
Therefore, during business design, we should try to define the prototype of the Business Method in the interface or abstract class, and implement the business method through the specific implementation class (subclass, the modification of the Business Method content does not affect the calling of the business method at runtime.
Figure 3 dependency principle diagram
4. The interface segregation principle ISP)
Using multiple interfaces related to a specific customer class is better than using a common interface that covers multiple business methods.
The ISP principle is another enabling technology that supports components such as COM. Without ISP, the availability and portability of components and classes will be greatly reduced.
The essence of this principle is quite simple. If you have a class for multiple customers, creating a specific business interface for each customer, then it is more effective to make the customer class inherit multiple specific business interfaces than to directly load all the methods required by the customer.
Figure 4 shows a class with multiple customers. It serves some customers through a huge interface. As long as the method for customer a changes, Customer B and customer C will be affected. Therefore, you may need to recompile and release the SDK. This is an unfortunate practice.
Figure 4 services with integrated interfaces
Let's look at the technology shown in Figure 5. Each method required by a specific customer is placed in a specific interface, which is inherited and implemented by the service class.
Figure 5 service class design separated by interfaces
If the method for Customer A is changed, Customer B and customer C will not be affected or need to be re-compiled or re-released.
The above four principles are commonly used in object orientation. In addition to the above four principles, there are also some common experiences, such as the class structure level should be three to four layers, and the class responsibilities should be clarified (one class corresponds to one specific responsibility) for our reference in object-oriented design. However, from the above several principles, we can see that these classes present the relationship of tree topology in geometric distribution, which is a good and open linear relationship with low design complexity. In general, in software design, we should try to avoid designing relationships with closures and loops. They reflect a large degree of coupling and design complexity.