Document directory
- 1. Dependency
- 2. Dependency inversion
- 3. Control inversion (IOC)/dependency injection (DI)
Just after the National Day, I should give some friends a question and summarize the popular understanding of IOC in spring, that is, Di.
Wm5920 explanation:
IOC control inversion: this refers to the process from code control to IOC container control of the Creation object instance. In fact, you control the XML file, focusing on the principle.
Di dependency injection: when an object instance is created, the property value or other object instances are injected for this object, focusing on implementation.
IOC, di Mode 1. Dependency
Dependency is associated. If dependency is used locally, dependency is dependent on it. A system cannot completely avoid dependency. If a class or module does not use it in the project, congratulations, you can remove it from the project or exclude it, because none of them will depend on it. The following is a simple example:
/// <Summary> /// the user plays the media file /// </Summary> public class operationmain {public void playmedia () {mediafile _ mtype = new mediafile (); player _ player = new player (); _ player. play (_ mtype) ;}/// <summary> // player /// </Summary> public class player {public void play (mediafile file) {}}/// <summary> /// media file /// </Summary> public class mediafile {}
The above is a simple example of a user playing a file with a player. The user operation is the playmedia method in the operationmain class. Open a player and select a file for playing. First, let's look at the dependency between them. We can simply find three dependencies.
- Player depends on mediafile
- Operationmain depends on player
- Operationmain depends on mediafile
2. Dependency inversion
The demand has increased. We need to abstract different players and play different files to reduce coupling.
Coupling is the dependency. If the dependency is complex, it is difficult to maintain the dependency. The less the dependency, the lower the coupling relationship, and the more stable the system. Therefore, we need to reduce the dependency.
Fortunately, Master Robert Martin proposed the object-oriented design principle-Dependency inversion principle:
- A. Upper-layer modules should not depend on lower-layer modules. They both depend on an abstraction.
- B. abstraction cannot depend on visualization, while it depends on abstraction.
Understanding:. the upper layer is the user, and the lower layer is the user. As a result, the upper layer is dependent on the lower layer. The lower layer changes, which naturally affects the upper layer, resulting in system instability, and even a pull. How can we reduce dependencies? That is, both the upper and lower layers depend on another abstraction. This abstraction is relatively stable, and the whole process is relatively stable.
B. object-oriented programming is aimed at abstraction or excuse-oriented programming. The abstraction is generally stable. The specific implementation of abstraction must depend on abstraction. abstraction should not depend on other specifics, but on abstraction.
In the player example above, we have found the dependency. Now we need to optimize the dependency according to the dependency inversion principle.
According to the following principles:
- The player depends on mediafile, so that both the player and mediafile depend on an abstract imediafile.
- Operationmain depends on the player. It is easy to implement. operationmain and player both depend on an abstract iPlayer.
- Operationmain depends on mediafile, which is easy to handle, so that operationmain and mediafile both depend on an abstract imediafile
- The iPlayer cannot depend on a specific mediafile. It should depend on the abstract imediafile of a specific mediafile.
The structure is very simple, so the code is roughly as follows:
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 09:59:56 ** @ Class description: the user plays the media file */public class operationmain {public void playmedia (iPlayer, imediafile) {iPlayer. play (imediafile );}}
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 10:03:23 ** @ Class description: media file to be played */public interface imediafile {public void getsetpath ();}
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 10:03:39 ** @ Class description: */public class mp3file implements imediafile {@ overridepublic void getsetpath () {// todo auto-generated method stubsystem. out. println ("playing a file in [MP3] format ");}}
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 10:03:39 ** @ Class description: */public class mp4file implements imediafile {@ overridepublic void getsetpath () {// todo auto-generated method stubsystem. out. println ("playing files in [MP4] format ");}}
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 10:02:41 ** @ Class description: playing component abstract class */public interface iPlayer {public void play (imediafile );}
Package IOC;/*** @ Author: -AK47 * @ Creation Time: 10:02:59 ** @ Class description: */public class player implements iPlayer {@ overridepublic void play (imediafile) {imediafile. getsetpath ();}}
Test procedure:
Package IOC; import Org. JUnit. test;/*** @ Author: -AK47 * @ Creation Time: 10:08:25 ** @ Class description: */public class ioctest {@ testpublic void testioc () {operationmain OPMN = new operationmain (); OPMN. playmedia (new player (), new mp3file (); OPMN. playmedia (new player (), new mp4file ());}}
Run:
Play [MP3] files. Play [MP4] files.
The code above is abstracted. We can see that the purpose is to reduce the dependency, but it seems that the dependency relationship has increased, such as the playmedia method, and the dependency interface and specific implementation are added, however, the interface is stable and can be ignored. The specific implementation is changed. This dependency is still required. To play a file, you must use a specific player and file.
3. Control inversion (IOC)/dependency injection (DI)
It should be emphasized that what IOC and di mean
In real life, a specific player has nothing to do with a specific media file. You can play an MP3 file for it or an MP4 file for it, when you delete your media files, the player is still there. The control of the specific player and file to be played is all owned by our users.
The preceding example basically achieves isolation. The specific player is isolated from the specific media. The specific player is only related to the media interface and player interface. However, the specific objects in the playmedia method are hard to write, and the control is very small. If I want to use Baidu audio and video for playing, I want to change the code for a new music, how to transfer the control?
We can create through reflection and write the specific file name in the configuration file. At this time, the client code does not need to be changed. You only need to modify the configuration file, and the stability is improved as follows:
public void PlayMedia() {IMediaFile _mtype = Assembly.Load(ConfigurationManager.AppSettings["AssemName"]).CreateInstance(ConfigurationManager.AppSettings["MediaName"]);IPlayer _player = Assembly.Load(ConfigurationManager.AppSettings["AssemName"]).CreateInstance(ConfigurationManager.AppSettings["PlayerName"]);_player.Play(_mtype);}
Which object is controlled by the configuration file? The control of the specific object is handed over to the configuration file, which is also a common inversion of control.
Control inversion IOC is short for inversion of control. It refers to the transfer of control of an object to a third party. For example, if the transfer is made to an IOC container, it is a factory creation and what object do you want, it will give you some objects. With the IOC container, the dependency will change, and the original dependency will be gone. They all depend on the IOC container, use the IOC container to establish the relationship between them.