Concept of Component Design Principles (II)

Source: Internet
Author: User

The first three component design principles focus on the cohesion of components. Starting from this article, the three principles to be introduced will focus more on the coupling between components, which is more difficult than the first three principles, I will explain it with some examples. The main reference is still Robert C. martin's"Principles of package and Component Design" in Agile Software Development: Principles, patterns, and practices. When explaining the component design principles, the meanings of components are similar to those of packages, indicating the organizational structure containing multiple elements. As the following describesNo-ring dependency principle (ADP),Stable dependency principle (SDP)AndStable abstraction principle (SAP)It is relatively complicated. Therefore, I decided to explain it separately and try to make every explanation of each principle comprehensive and in-depth. If you have any questions, please feel free to contact me more!

 

Principle of component coupling: Principles of component coupling: Stability)

 

The Acyclic Dependencies Principle (ADP)

Allow no cycles in the component dependency graph.
The component dependency graph does not allow loops.

 

Ring dependency and no-ring dependency

ADP is easy to understand, that is, there should be no circular dependency between components. For some large projects, multiple components are inevitable. Different components may be developed by different development teams. When a component changes, all other components dependent on it will also need to be re-integrated and tested. If there is a ring in the dependency, it will lead to circular dependency, this makes it difficult to upgrade or re-release a component because the impact scope of the modified component becomes very large.

First, let's take a look at the example of a loop-free dependency, as shown in 1. In Figure 1, component3 depends on component4 and component5. To modify component3, you only need to relink component4 and component5 without any impact on component2, modifying component4 or component5 will affect component3 and component1 (You can find all affected components by Reverse dependency.), Developers who develop component3 and component1 can decide whether to integrate with the new version of component4 or component5 and when to integrate.

 

Figure 1 NO-ring dependency

The dependency graph shown in 1 isDirected Acyclic Graph (DAG). When releasing the entire system, you can first compile, test, and release component4 and component5 in the ascending order, then component2 and component3, and finally component1, this development and design process is very clear and easy to operate.

If we do not properly design the component, it will cause a circular dependency between components, as shown in Figure 2:

Figure 2 circular dependency

As shown in figure 2, this circular dependency will cause many problems in the system: to release a new version of component3, you only need to re-link component4 and component5, because component4 and component5 are no longer dependent on other components, the time and workload are relatively small. However, in a system with circular dependencies, component5 depends on component1 and component1 depends on component2. As a result, all components of the system need to be re-compiled and linked, this makes the release of component3 very troublesome, and the cost of re-building (integration) the entire system increases dramatically during each release, A complete build will be performed for the release of a component, which will seriously affect the system development progress ,.

In addition, system integration and testing become increasingly difficult. The increasing coupling, modification, and expansion of systems are troublesome. In some more complex projects, if a large number of circular dependencies exist, the Compilation Time will grow with the number of modules in a geometric level. Without a doubt, it is absolutely intolerable!

In this ring-dependent system, the component build sequence is also a big problem. Because there is a circular dependency between components, which component should be built first? When compiling a component, the component on which it depends comes from where it actually becomes a"First chicken or eggIn some programming languages, this problem cannot be solved!

 

Eliminate ring dependency

Bob mentioned two methods in ASD to transform the circular dependency between components into Dag. The following describes these two methods in detail, which also integrates some of my own opinions, hope to help you.

 

1. Apply the dependency-inversion principle (DIP): applies the dependency reversal principle.

Let me take the examples in ASD to illustrate how to implement them, as shown in 3:

  Figure 3 using dip to eliminate dependency Loops

3. In a system, if we can eliminate the dependency between mydialogs and myapplication, we can eliminate the circular dependency. Through analysis, we know that Class X in component mydialogs depends on class Y in component myapplication. At this time, we can make the following refactoring:

(1) Add an interface to component mydialogs. the X server shown in 3 depends on the X interface;

(2) Use class y as the implementation class of interface X server.

After the preceding two steps, the dependency between mydialogs and myapplication is changed from mydialogs dependency to myapplication dependency. The compilation order is to compile mydialogs, and then compile myapplication. Because X is used to program abstract interfaces, this makes the system more scalable.

This refactoringConverts the dependencies between components into reverse abstract dependencies to eliminate circular dependencies.

 

In addition, if there are too many classes involved and you do not want to add too many interfaces to the original components, you can also add a new component that contains a series of interfaces, the original component is programmed for this component that contains multiple interfaces, as shown in Figure 4:

Figure 4 Add abstract components to eliminate dependency Loops

In Figure 4, a new abstract component abstractcomponent is added. component5 no longer directly depends on component1 and contains a group of interfaces in abstractcomponent. The implementation classes of these interfaces are in component1, component5 is programmed for abstract interfaces. Therefore, component5 only needs to rely on abstractcomponent. In this case, the compilation order is abstractcomponent --> component5, component4 --> component3, component2 --> component1. It can be seen that the introduction of new abstract components completely eliminates the ring dependency, in addition, because abstractcomponent contains a large number of interfaces, the system has better scalability. If you provide a set of new classes that implement interfaces in abstractcomponent, the original system does not need to make too many modifications, in line with the principle of open and closed.

 

2. Create a new component that both of the components depend on: Create a new component with a common dependency

Taking Example 2, we can create a new component that both component1 and component5 depend on. For example, we can extract the classes dependent on component5 in component1 and encapsulate them into new components, for example, in newcomponent, both component1 and component5 will depend on newcomponent, and newcomponent will become the first compiled component, as shown in Figure 5:

Figure 5 Add a new component to eliminate the dependency Ring

In actual development, as the project scale expands and applications increase, dependencies between components will change (the relationships between classes in components will be further clarified ), we need to monitor the Ring Structure in the component at any time. If a ring structure exists, you must use some method to remove it. This may require the creation of some new components, resulting in increasing dependency chains and more complex dependencies. However, to eliminate dependency loops, it is necessary to add new classes or components as appropriate, because the existence of the dependency ring is harmful ,!

 

In short,ADP means that the component dependency graph cannot have a ring. If so, we should try to eliminate the ring dependency!

[Author: Liu Wei http://blog.csdn.net/lovelion]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.