Yesterday, I went through a friend's space and saw a discussion about control reversal. I wrote a piece of message, but after a long time, I didn't touch these words, so I checked some information, sorted it out again, and discussed it with you.
Before sorting out, we should first talk about "dependency". What is dependency? dependency is association. The "association" defined in UML is the most extensive one, it is shown that there is a root line between the two class diagrams. I personally understand that in C/C ++, A includes another header file B, Java /. in net, if a using has another package or unit B, the two are associated. A depends on B. If there is no dependency, why should a include B? It must have been a call (B. Call () or reference (such as B as a class variable or parameter variable ). So I understand this as dependency.
Assuming that B is changed on the internet, A is also dependent. I think it may be misleading, because assume that B is changed internally and the interface remains unchanged. Why should a be changed? Or B adds an interface a that does not call, And A does not need to be changed, but a still depends on B.
This is about dependency. Next we will discuss the three terms of the title. I don't want to explain them one by one here, because there may be a sense of Case-based discussion. I want to discuss some essential things with you.
In the face of a complex transaction, what are our solutions? There is no doubt that it is a decomposition. If you think of the leaders who are dedicated to every day, it is impossible to ask questions in every case, because my personal energy is limited, the complexity changes by an order of magnitude as the scale increases. How do leaders handle this problem? It is divided into Marketing Director, Financial Director, Technical Director, Administrative Director, and other roles. Each role is responsible for one role. When the time comes, it will be okay to report their problems to the leaders, and the leaders will make decisions.
In the analogy of software, the director here is a module, the report is the interface in Oo, and the lead is the framework, concatenates all modules to accomplish a set big goal (for example, to achieve a specific solution ). What about engineers or financial personnel? There is no doubt that a specific class is an execution body that implements a specific function, such as a programming job or organizing a report.
It can be seen that some of these actions within the company can be mapped to the entire software architecture every day around us. So what kind of thinking can we get from the company's organizational behavior? First, with decomposition, we can reduce some complexity. But next, what is the most complicated software? Is change. The same is true for the company. The outside world is facing a lot of survival pressure. There may be some internal problems at the company level or individual level, and even personnel hopping may bring some risks. How can the company deal with such problems? Isolation. Isolate the easily changed from the relatively stable ones that are not easy to change, so that the control can minimize the impact. So what is isolation implemented? Abstract. Why? This is because the abstraction is relatively stable.
Here is a funny example: a son who is about to be a leader asks his former father how he can make a smooth move. His father says that you cannot lie because the common people will not agree, I can't tell the truth, because the leaders will have opinions on you, and the son thinks for a long time and asks: what should I say? His father said with a deep sense: empty talk
Joke is not only funny, but also reflects some truth. It is useful for empty talk because it is abstract, and abstraction does not involve specific data or transactions, so it is stable, it is not easy to change, and it is basically correct. So we often hear something similar in the public: "We need to unite and work hard to improve work efficiency and reduce work costs ..." Can you say this is wrong? Of course not, so since it is very stable, this dependency is very reliable.
The same is true for the company. If a leader is dependent on the engineer's ability and asks this question one day, what if one day the engineer changes? The lead handles some very important macro-level transactions and cannot have any major impact on a small engineer. Therefore, he will not rely on engineers directly, instead, it relies on an abstraction called technical director. If an engineer leaves, change the engineer to replace what he has previously done. What he has done is the interface set by the Technical Director, which has no impact on the leadership, only in this way will the changes be isolated.
Think about the software in turn. In fact, the above describes some very meaningful practices for the software. The very important thing in OO is that the modules depend on abstract interfaces rather than specific implementations, why? The abstraction is relatively stable. I/O must have the two abstractions of read/write. For disk or keyboard, the Implementation below is different. Through this architecture, the flexibility and maintainability of the software can be maintained.
What is more enlightening from the company's behavior is the company's organizational structure. The company's hierarchy can be mapped to the software hierarchy, and the leadership is the framework layer. The following interfaces are used to control classes. We should do the same without a doubt when designing software. Design the Framework Design Interface, design the interface, and then call the APIS or classes to implement a specific implementation, such as database read/write or socket data sending and receiving. Each place has its own opposite responsibilities and does its part. If there are APIs, it is equivalent to a large group of engineers doing both business negotiation and coding. The results are the same: chaotic.
Finally, let's get down to the truth. Let's talk about the three terms mentioned above, relying on the inverted Dip (dependency inversion principle). In Uncle Martin's masterpiece agile development: principles, practices, and patterns, we have clearly described them, the high-level module should not depend on the underlying module, but on both of them. The underlying module implements abstraction. I believe this has been discussed clearly above. It is like a leader who depends on engineers to do things in the final sense, but does not depend on you directly, but on the abstract of a director. This is an inversion. Where is it? This dependency goes down and introduces a new middle layer, an abstraction. In the past, the traditional process was designed as a line of dependency from top to bottom. Now it is a line of leadership to director, and then an association line from bottom to top engineer to director.
Inversion of control is actually a bit similar, mainly because the concept of the framework is put forward in OO. What is the framework? According to the description in the Brother Wang's "Tao nature, it is mainly a dynamic environment body that can handle some complicated transactions or logic. It is not the same as the static behavior of the class library. Class Libraries are services waiting for others to call one by one. So where is the control reflected? In traditional practice, we call class libraries in our own programs to complete functions. Class Libraries are our execution bodies, but logical algorithms are implemented by ourselves. This is our own control, but the framework is different, and the logic algorithm is implemented by it. We only need to provide several required interfaces or execution bodies. This is a reversal. It is controlled on the Framework side, which simplifies the workload and does not need to be repeated in some common business scenarios. In this case, the control reversal mainly applies the template method and other modes. In my opinion, the observer mode is a typical instance for controlling sending and forwarding, because the query observer is a logic implemented by the subject side, the observer only needs to implement the notify interface. So there is nothing.
Dependency injection is actually not a hierarchical concept compared to the above two, mainly manifested in the use of constructor or interface to complete the binding of a specific work class. This is a good idea, for example, if you want to complete a development job, you can ask the director to specify engineer a to complete the job. However, for greater flexibility, you can ask the director to provide such an interface.
Assignjob (engineer Engineer) {engineer. Do ();}
In this way, the director can ask Jia to complete the job by default. However, if a asks for leave for some reason, he can use this interface to ask B to do the job, in this way, it becomes elastic when changes occur. By the way, most software uses config to achieve greater flexibility, because. net/Java introduces the concept of reflection, you can dynamically create classes during runtime, this function is very powerful, refer to the above business needs, we can place the class name in config and load different classes through reflection to achieve different implementations. This is also the most basic practice of many frameworks (such as structs ).
The above are some personal opinions. I feel that some oo terms sound mysterious. In fact, this is also the case. As long as you master the basic principles of OO, you can basically derive them. Haha. I hope to share my thoughts with you
With the more brilliant explanation of the Brother Wang: http://www.contextfree.net/wangyw/source/dip_ioc.html