Recent online two nouns have a high frequency, so I read the masterpiece of Martin Flower and some related articles, and share my experience with you.
Introduction
In fact, IOC mode is not a new thing, it is a very common concept (or structure), and the template method in GOF is the structure of IOC. As the name suggests, IOC is controlled. The famous Hollywood Principle: "Don't Call US, We Will Call You", and Robert C. Martin's dependency inversion principle, DIP is the embodiment of this idea. Dependency INJECTION is an extension of Martin Flower to IOC mode, and we start with a simple instance.
Consider a Button to control the opening of LAMP.
Get this feature, I can't think about the following class diagram and write the code.
Public class button {
PRIVATE LAMP LNKLAMP;
Public void poll () {
lnklamp.turnon ();
}
}
But immediately discovered this design, but the Button class relies directly to the LAMP class, which means that the Button class will be affected when the LAMP class changes. In addition, it is impossible to reuse the Button class to control another object similar to LAMP. That is, Button controls LAMP and can only control LAMP.
Obviously, I violate the "high-level module should not depend on the underlying module. Both should depend on abstraction; abstraction should not depend on concrete implementation, the details should depend on abstraction" (DIP principle).
Taking into account the above problems, it is naturally that it should be abstracted an interface to eliminate Button's dependence on LAMP, so the design is designed:
In this way, we inverted Button's dependencies, so that LAMP relies on the Switch-de-DechableDevice interface, and SwitchableDevice does not depend on the Button class, and any object knows how to manipulate the interface can control LAMP. At the same time Button is not just controlling LAMP, but also controls the same implementation of the SwitchableDevice interface such as Computer, Cell Phone, and more. Looking back, this practice seems to be seen, patted his head, oh! Is this not a STRATEGY mode? ! It is, inadvertently, I applied design mode (a bit proud ~~~~~).
Now, consider a problem, just inverted the dependencies, but if you control the Button as an application to control the LAMP or achieve the SwitchableDevice Computer, Cell Phone, etc., the code may be as follows:
Public class button {
Private switchableDevice lnklamp;
Public button () {
Lnklamp = new lamp ();
}
...
}
That is, the dependencies such as "Creates" still exist between Button and LAMP.
In order to relieve this dependency, you first look at the GOF can do something. Obviously, this place should use the Factory mode to handle the object's creation to the Factory Class, though unlocking the coupling relationship between the LAMP component and our application Button, but the creation of the component is still explicitly explicit. , Still need to recompile when the component changes. In addition, it is also a way to unpacking the coupling by a serviceLocator to the Look Up. See it, you can't help but think that EJB is not so real. U Are Right! Rod Johnson is called this The way is Dependency Look Up, but this approach has its drawbacks, such as unable to detach from the container environment, as well as Unit Test, etc.
"Don't call us, we will call you", this principle revealed that we should change a thinking, should not create an instance of the specific object in the application class, but should be inserted (plug) or injection of the specific object instance or injection (Inject) to the application class, this is probably the origin of the injection name.
This implementation needs to establish an Assembler between the application and the calling assembly to disseminate the dependence between the two, it seems to have no difference with the previous way, and look at the structure:
Carefully check it to find it or have a big difference, depending on the relationship, that is, in the process, it is still inverting the dependencies. LAMP Injections its creation process through Assembler to Button, thereby eliminating the coupling between the two, increasing flexibility.
Let's take a look at the specific implementation, with its different implementations in PicoContainer and Spring, representing two types of Dependency Injection, That is, Constructor Injection and Setter Injection.
Private mutablePicocontainer configureContainer () {
MutablePicocontainer Pico = New DefaultPicOContainer ();
Pico.registerComponentImplement (SwitchAdingDevice.class, Lamp.class);
Pico.registerComponentImplement (Button.Class);
Return Pico;
}
You can then get the implementation class through the MutablePicocontainer's getComponentation method, calling its POLL method to control the switch of the LAMP, so that the coupling between the two is completely eliminated through the Assembler provided by the PicoContainer.
Spring, connects the two through an XML format profile, when using ApplicationContext, then calls its method to implement, and the coupling relationship is also eliminated.
Behind I will pay attention to the implementation of IOC and AOP in Spring, and I will share my heart in the form of blog.