1 Introduction
Object-oriented thinking has been deeply rooted, but it is not an easy thing to develop outstanding applications with object-oriented ideas. It is based on object-oriented ideas, and people have analyzed a lot of applications, summarized, summarizing the design model. The classic definition of Alexanders gives the mode is that each mode describes a problem that has emerged in our environment and then describes the core of the solution. In this way, you can use the existing solutions in numerous times without having to repeat the same work again [2]. Design mode technology has received extensive attention, research and application in the classic books of GOF. The various frameworks that emerge in spring after the rain is the model of design model. The IOC mode is more widely used in various frameworks.
2 IOC mode
2.1 IOC Mode Introduction
IOC (Inversion of Control) mode is not a new thing, it is a very common concept, 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 exemplary explanation of Martin Flower to IOC mode [2]. IOC is a design pattern for solving the component (actually also a simple Java class) between dependencies, configuration, and lifecycles, with the processing of component dependencies is the Essence of IOC. The practical meaning of IOC is to extract (reverse) between the dependencies between components, and is configured by the container. In this way, there is no association between Hard-Code between each component, and any components can be reused to maximize. After using IOC mode, we no longer need to manage the dependencies between components, only need to declare this dependency from the container. It seems that the control of the relationship between the components is inverted, and this dependency is no longer to create this dependency to hand over the container (for example, PicoContainer, Spring "will introduce it later.
We look from a simple example and consider an example of a Button control LAMP:
Public class button {
Private lamp lamp;
Public void push () {
Lamp.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 control the Button class to control similar to LAMP (such as a COMPUTER having a Turnon function). That is, Button controls LAMP and can only control LAMP. Obviously violates the "high-level module should not depend on the low-level module, both should depend on abstraction; abstraction should not depend on concrete implementation, the details should depend on abstraction" (DIP principle). Considering the above problems, natural thinking should abstract an interface SwitchEDevice to eliminate Button's dependence on LAMP, so designed as follows:
Public class button {
Private switchableDevice lamp;
Public button () {
Lamp = new lamp ();
}
}
Think more, although our Button can now control the CMPUTER of the Switch, Directone, but the Button and Lamp classes still have a dependency such as CREATE. In order to solve this dependency, the classic GOF mode is created using the Factory mode, and the creation of the object is created, but this creation is still displayed, and the component changes still require recompilation. The J2EE classic service Locator mode is used, if you want to get the Button component in another system, you must modify its source code to use another system's serviceLocator. In other words, this component does not have portability. This is the truth that needs to be rely on, allowing the component's creation, configuration, and life cycle to be managed by external containers. 2.2 IoC type
2.2.1 Type of IOC
We first take a look at the type of IOC before explaining thorough decoupling using IOC mode:
2.2.1.1 Method-Based (M) IOC
The components are delivered in each method call. If the method needs a component, the component is passed to the method as a parameter.
2.2.1.2 Interface-Based (i) IOC (Type 1)
Use the interface such as serviceable, configurable, etc. to declare dependence. The EJB container is a Type1 weight-level container, deploying the EJB component in its internal EJB component to declare dependencies.
2.2.1.3 Setter-based (s) IOC (Type 2)
Use setters to set up the dependent components. Take the dependent component as an attribute, dynamically set the dependent component through the Setters method.
2.2.1.4 Constructor-Based (C) IOC (Type 3)
Use constructor to declare dependence. Rely on relationships by passing component parameters into constructor.
2.2.2 Comparison of IOC types
In these types, Type 3 invading is smaller. Because in object-oriented theory, constructors is not part of an object contract. According to Bertrand Meyer, you should never call the Constructor directly, because this means that the Client code is bound to the implementation (rather than contract). Then, since the Constructor is not part of the object contract, exposing meta information in the constructor will not affect the object contract. Although Type 2 is also very good, Setter is a target contract, and a setter is used for IOC how much "destructive", and too much exposure to the internal object of the internal object through the setter method, which lost the package of the object. .
Type 2 is very suitable as a Bean plant as an app. If it is more dynamic assembly, it may be a better Type 3. In terms of definition, Type 2 is setter based on Setter, and Type 3 is based on the constructor. Why is Type 2 more suitable for bean factory? Because setter is separate, it is legal for 0 ~ n of the bean factory to the defined N setter. TYPE 3 is a bit a bit trouble, not adapted to rely on more, the component's "meta" is embodied in the parameter list of constructors, and you must provide all the necessary parameters at once. If you need a lot of components, you need to pass a lot of parameters in the constructor, which will cause the constructor's parameters too long.
2.3 IOC container
Depending on the degree of intrusion of the container to the component, the IOC container can be divided into the following three categories:
2.3.1 Interface Injection
Corresponding to Type 1 IoC, use an interface to declare dependencies. Such IOC container intrusion is the strongest and needs to obtain components through context. Components need to implement specific interfaces provided by the container, so that the reuse of components is defined within the container. The representative of this type of container has apache avalon. Avalon is not very popular, although it is very powerful and has a long history. Avalon is a heavyweight container and looks more invasive than the new IOC solution. 2.3.2 Setter Injection
Corresponding to Type 2 IOC, setting the dependent component using setters. Such IOC containers require components to provide Accessor methods, depending on the SETTER method. According to the Java component model, the average JavaBean will have an Accessor method, so the reuse of the component has no restrictions. The representative of this type of container has Spring, and it also implements a third type of IOC container. Spring is a very active, excellent open source project. It is a framework of architecture multi-layer J2EE system based on IOC and AOP (Aspect-Oriented Programming, aspect-oriented), which is elegantly implemented MVC framework, supports the use of Declarative Transaction Management. More importantly, the Spring Frame has no invasiveness [3].
2.3.3 Constructor Injection
Corresponding to Type 3 IoC, use constructor to declare dependencies. Such IOC containers require components to configure dependencies by constructing. Similar to the second IOC type, there is no problem with the component reuse. And constructor inJection is more stringent, fully configure component dependence in accordance with Contract. The representative of this type of container has a PicoContainer.
PicoContainer is a lightweight and emphasizes the expression dependence through constructor, not the JavabeaN property. Unlike Spring, its design allows each type of object definition (probably because it rejects the limitations caused by metadata outside the Java code).
2.4 Using IOC container to implement control reversal
Let's take a look at how to use the IOC container PicoContainer to achieve the example of this article, the main code is as follows:
Private mutablePicocontainer configureContainer () {
MutablePicocontainer Pico = New DefaultPicOContainer ();
Pico.registerComponentImplement (SwitchAdingDevice.class, Lamp.class);
Pico.registerComponentImplement (Button.Class);
Return Pico;
}
Then you can get the implementation class through the MutablePicoContainer's getComponentation method, call its PUSH method to control the LAMP switch, so that the coupling between the two is completely eliminated by the Assembler provided by the PicoContainer.
Spring links the two through a configuration file in an XML format. When used, you get the Button Bean by ApplicationContext, and then call its method implementation, and the coupling relationship is also eliminated.
3 summary
IOC has the following advantages:
1. Because components do not need to find collaborators at runtime, they can write and maintain more simple. For the same reason, it is easy to write test code to make the class test easier.
2. No external dependence is required. Can develop and test components in any environment without a special deployment environment, like JNDI, EJB. And it is convenient to reuse and changing in different IOC containers. 3. The entire system is easier to assemble and configure. Most business objects do not depend on the IOC container. This makes it easy to use legacy code, and it is easy to use objects, whether or not in the container or in the container.
4. Increase the degree of reuse of components, provide software generation efficiency.
Of course, the IOC is inconvenient to understand compared to the usual method, because component creation is implicit. So lightweight, no invasive IOC containers still wait for us to study and develop.