Dependency injection java

https://blog.csdn.net/coderder/article/details/51897721

  1. Introduction
    In the field of software engineering, dependency injection (Dependency Injection) is one of the most common ways for implementing inversion of control (Inversion of Control) in. This paper describes the dependency injection principle and common implementation, application scenarios and focus on introducing the advantages of this young design pattern.

  2. Why Dependency Injection
    Inversion of Control for decoupling, who is and who is the de-coupling of? This is the first question I produced in the initial understanding of dependency injection time.

Let me quote part of the code Martin Flower used in interpreting introduction injected to illustrate the problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MovieLister {
private MovieFinder finder;

public MovieLister() {
    finder = new MovieFinderImpl();
}

public Movie[] moviesDirectedBy(String arg) {
    List allMovies = finder.findAll();
    for (Iterator it = allMovies.iterator(); it.hasNext();) {
        Movie movie = (Movie) it.next();
        if (!movie.getDirector().equals(arg)) it.remove();
    }
    return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
}
...

}
1
2
3
public interface the MovieFinder {
List findAll ();
}
We created a class called MovieLister need to provide the list of movies, it moviesDirectedBy method provides a way to search for a movie based on the name of the director. Search movie really responsible is to achieve MovieFinderImpl MovieFinder interface, our MovieLister MovieFinderImpl class creates an object in the constructor.

Now it seems that everything is good. However, when we want to modify the finder, the finder is replaced with a new implementation (such as MovieFinder add a parameter to indicate the source of the data which Movie Database), we not only need to modify MovieFinderImpl class, we also need to modify to create MovieFinderImpl in MovieLister code.

This is coupled to process dependency injection. This created MovieLister MovieFinderImpl in a way that not only dependent on MovieFinder MovieLister this interface, it also depends on the MovieListImpl this implementation. This code that creates an object of another class, and hard-coded (hard-coded strings) directly in a class, and hard-coded numbers (magic numbers) as the coupling of a lead bad taste, we take this bad taste called hard initialization (hard init). At the same time, we should also remember that like the same hard-coded in mind, new (object creation) are toxic.

The main disadvantages Hard Init brought twofold: 1) actually present modification described above, create a need to modify the code at; 2) is not easy to test, class (the MovieLister above) created in this way alone can not being tested, their behavior and MovieFinderImpl tightly coupled together, at the same time, can lead to problems readability of code ( "If a piece of code is not easy to test, then it must not be easy to read.").

  1. Dependency injection implementations
    dependency injection really is not magic, we have a lot of daily code uses dependency injection, but little attention to it, rarely take the initiative to use dependency injection to decouple. Here we briefly explain Lai implement three of the injection method.

2.1 constructor injection (Contructor Injection)
I think this is the easiest way to dependency injection, we modify the above code in the constructor MovieList, making the realization MovieFinderImpl created outside MovieLister class. In this way, MovieLister it depends only on us MovieFinder interfaces defined without depending on the realization of the MovieFinder.

1
2
3
4
5
6
7
8
public class MovieLister {
private MovieFinder finder;

public MovieLister(MovieFinder finder) {
    this.finder = finder;
}
...

}
2.2 setter injection
Similarly, we can add a setter function to create a good MovieFinder incoming object so that the object is also to avoid hard init in MovieFinder in.

. 1
2
. 3
. 4
. 5
. 6
public class the MovieLister {
S ...
public void setFinder (the MovieFinder Finder) {
this.finder = Finder;
}
}
2.3 interface injection
interface injection setter using the interface to provide a method that achieves follows.
To create an interface using the first injection.

1
2
3
public interface InjectFinder {
void injectFinder(MovieFinder finder);
}

After that, we let MovieLister implement this interface.
. 1
2
. 3
. 4
. 5
. 6
. 7
class the implements the MovieLister InjectFinder {
...
public void injectFinder (the MovieFinder Finder) {
this.finder = Finder;
}
...
}

Finally, we need to create implementation is dependent MovieFinder according to different frameworks.

  1. Finally,
    dependency injection is reduced and the dependence between the dependent type coupling, is dependent upon the type of modification achieved without modifying the implementation-dependent type, while the dependence of the type of test may be more convenient to use mocking object to replace the original It is dependent on the type, in order to achieve the object of the dependent independent unit testing.

Finally, it should be noted that the dependency injection just an inversion of control implementation. Inversion of Control Another common implementation is called dependent lookup.

参考
Inversion of Control Containers and the Dependency Injection pattern
How to Think About the “new” Operator with Respect to Unit Testing
依赖注入

Guess you like

Origin www.cnblogs.com/paulkg12/p/12122058.html