Introduction to reverse IoC and reverse ioc
Control reversalIoCIntroduction
In actual application development, we need to avoid and reduce the dependency between objects as much as possible, that is, to reduce the coupling degree. Generally, business objects are mutually dependent. Business Objects and Business Objects, Business Objects and persistence layers, and Business Objects and various resources all have one or more dependencies. But how can we reduce the dependency between classes? This is the problem to be solved by the core IoC in this article. The following describes the IoC from two major points:
(1)IoCAndDIBasic Concepts
IoC (Inversion Of Control) is the Inversion Of Control. Specifically, containers Control the dependencies between business objects, rather than directly controlling them by code in traditional methods. The essence of control reversal is that control is transferred from application code to external containers. The transfer of control is called inversion. The benefit of the transfer of control right is that the dependency between business objects is reduced, that is, decoupling is achieved.
There are two implementation strategies for IoC:
1)Dependency search:The controlled objects in the container use the container API to find the resources and collaboration objects on which they depend. Although this method reduces the dependency between objects, it also uses the container API, which makes it impossible for us to use and test objects outside the container;
2)Dependency injection (also knownDI:Dependency Injection):The object only provides a common method for the container to determine the dependency. The container is fully responsible for the Assembly. It will pass the objects that conform to the dependency to the desired object through attributes or constructors. The method of injecting dependency through properties is called value-setting method injection, and the method of inputting constructor parameters is called constructor injection.
The advantages of dependency injection are as follows:
Separate query dependent operations from application code;
Controlled objects do not use specific APIs of the container, so that our controlled objects can be used independently from the container.
(2)IoCInstance description
IoC represents an idea and a development mode, but it is not a specific development method. To understand the concept of IoC, the simplest way is to look at its practical application. The following describes several instances to explain the meaning of IoC.
When developing an application system, we need to develop a large number of Java classes. The system will use these Java classes to call each other. The call relationship between classes is the most direct relationship between system classes. Therefore, we can divide the classes in the system into two categories: callers and callers. For example:
Figure 1: Call Method Problems
The development of software design methods and design patterns has resulted in three types of calling methods: self-built (new), factory mode (get), and external injection (set ), the external injection is the IoC/DI mode.
Either method has two roles: the caller and the called. The following describes the meanings of the three methods through examples. First, we set the caller as the Student object Student, and the called object as the Book object. The code function to be designed is for the Student to learn the Book knowledge.
From the GoF Design model, we are used to a way of thinking programming: Interface Driven Design Interface-Driven, Interface-Driven has many advantages and can provide different flexible subclass implementations, increase code stability and robustness. To demonstrate the differences between different methods when Student gets different Book objects, we use interfaces to design the called users. The Code implemented is shown in the following three classes:
// Book interface class public interface IBook {public void learn ();} // BookA implementation class public class BookA implements IBook {public void learn () {System. out. println ("learn BookA") ;}// BookB implementation class public class BookB implements IBook {public void learn () {System. out. println ("Learn BookB ");}}
Here, IBook is the book interface, which defines a learning interface learn () and defines two library classes BookA and BookB to implement this interface, indicating that they are two different books, the learn () method represents the learning process of different books respectively.
The following three methods are used to explain how to call the library class:
1) new -- self-created
Student to learn BookA, it is necessary to define a learnBookA () method and create BookA objects on its own. Similarly, to learn BookB, it is necessary to define a learnBookB () method, and create the BookB object by yourself. Then we create a Test. java class to create a Student object. We can call the learnBookA () and learnBookB () Methods to execute the learning processes of the two books respectively. The specific implementation code is as follows:
// Student class public class Student {public void learnBookA () {IBook book = new BookA (); book. learn ();} public void learnBookB () {IBook book = new BookB (); book. learn () ;}// Test and run public class Test {public static void main () {Student student = new Student (); student. learnBookA (); student. learnBookB ();}}
This method creates an IBook object by yourself when the caller Student needs to call the called IBook. The disadvantage of this approach is that the called user cannot be changed and the user is responsible for the entire life cycle of the called user. The specific format is as follows:
Figure 2: self-created Mode
2) get -- factory Model
All objects are created by yourself. Every call requires you to create the objects. The created objects are scattered everywhere, causing management troubles, such as exception handling. Therefore, we can extract the object creation process and create it in a Factory. All the objects needed can be obtained from the Factory.
For example, in the following example, a factory class BookFactory is created, and two functions getBookA () and getBookB () are added for this class to create the BookA and BookB objects respectively. Then create the methods in learnBookA () and learnBookB () in Student, and retrieve the two objects in the factory class respectively. The specific implementation code is as follows;
// Book factory public class BookFactory {public static IBook getBookA () {IBook book = new BookA ();} public static IBook getBookB () {IBook book = new BookB () ;}// Student class public class Student {public void learnBookA () {IBook book = BookFactory. getBookA (); book. learn ();} public void learnBookB () {IBook book = BookFactory. getBookB (); book. learn () ;}// Test and run public class Test {public static void main () {Student student = new Student (); student. learnBookA (); student. learnBookB ();}}
In this case, the difference with the first method is that a factory class is added and the code of the created object in Student is extracted to the factory class. Student gets the object to be created directly from the factory class. The advantage of this method is that the unified object creation is realized, and the caller does not need to care about the object creation process, just get it from the factory. The specific form is shown in Figure 3:
Figure 3: factory Mode
This method achieves a certain degree of optimization, making the code logic more unified. However, the creation of the object is still not flexible, because the acquisition of the object depends on the factory, and an intermediate process is added.
3) set -- External Injection
Obviously, the first method depends on the called object, and the second method depends on the factory. To completely solve the dependency problem, we canceled the factory class and added a learning method learnBook () for Student. The input parameter is the interface type IBook. When using the Student method, we first create a specific IBook object, and then inject the object into Student as the input parameter of learnBook (), and call the unified method learn () of The IBook interface () you can complete the learning process. The specific implementation code is as follows:
// Student class public class Student {public void learnBook (IBook) {book. learn () ;}// Test and run the public class Test {public static void main () {IBook bookA = new BookA (); IBook bookB = new BookB (); student student = new Student (); student. learnBook (bookA); student. learnBook (bookB );}}
This completely simplifies the methods of the Student class. The learnBook () method does not depend on a specific Book, but uses the IBook interface class, in this way, you only need to create an external IBook implementation object and input it to this method, which completely frees the Student class from dependency with a specific Book. In the preceding example, Test. java creates bookA and bookB objects respectively, and you can also call the learnBook () method of Student to make Student completely universal. The specific form is shown in Figure 4:
Figure 4: External injection mode
It can be seen that the set-External injection method is free from the shackles of dependency, and can be freely injected from the External. This is IoC, which obtains the object creation information to the external, the required components are provided by external containers.