Dependency Injection principle

Source: Internet
Author: User

Turn: Dependency Injection principle


Dependency Injection principle posted on 2015-08-01 |   Categories in Software Engineering | 3 Reviews 0. Preface

In the field of software engineering, Dependency injection (Dependency injection) is one of the most common ways to implement control inversion (inversion of controls). This paper mainly introduces the principle of dependency injection and the common way of implementation, with emphasis on introducing the application scenarios and advantages of this young design pattern. 1. Why dependency injection is required

Control reversal is used for decoupling, the solution is who and who's coupling. This was the first question I had when I first learned about dependency injection.

Below I quote Martin Flower to illustrate this problem in part of the code used to explain the introduction of injection.

1
2
3
4
5
6
7
8
9
Ten
-
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 Moviefinder {
    List findAll ();
}

We created a class called Movielister to provide a list of the movies needed, and it moviesdirectedby methods to provide a way to search for movies based on the director's name. The real responsibility for the search movie is to implement the Moviefinderimpl of the Moviefinder interface, and our Movielister class creates a Moviefinderimpl object in the constructor.

At present, everything is good. However, when we want to modify the finder to replace the Finder with a new implementation (such as adding a parameter to Moviefinder to indicate which database the movie data originates from), we need to modify not only the Moviefinderimpl class, You also need to modify the code in our Movielister to create Moviefinderimpl.

This is the coupling to be handled by the dependency injection. This way of creating Moviefinderimpl in Movielister makes Movielister not only rely on the Moviefinder interface, it also relies on the implementation of Movielistimpl. This code of the object that creates another class directly in one class, like hard-coded (hard-coded strings) and hard-coded numbers (magic numbers), is a bad taste that leads to coupling, and we can call this bad taste hard init. At the same time, we should remember that new (object creation) is poisonous as well as remembering hard coding.

The main disadvantages of hard init are two aspects: 1) When modifying its implementation as described above, it is necessary to modify the code at the creation point, and 2) to not be easy to test, the class created in this way (Movielister in the above) cannot be tested separately. Its behavior is tightly coupled to the Moviefinderimpl, and also causes the readability of the code ("If a piece of code is not easy to test, it must not be easy to read.") ”)。 2. How dependency injection is implemented

Dependency injection is not magical, and many of our daily code uses dependency injection, but we seldom notice it, and seldom actively use dependency injection for decoupling. Here we give a brief introduction to the three ways to implement Lai injection. 2.1 Constructor Injection (Contructor injection)

This is the simplest method of dependency injection I think, and we modify the Movielist constructor in the code above so that the MOVIEFINDERIMPL implementation is created outside of the Movielister class. In this way, Movielister relies only on the Moviefinder interface we define, not on the implementation of 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 pass in the created Moviefinder object, which also avoids the hard init object in Moviefinder.

1
2
3
4
5
6
public class Movielister {
    s ...
    public void Setfinder (Moviefinder finder) {
        this.finder = finder;
    }
}

2.3 Interface Injection

Interface injection uses interfaces to provide setter methods, which are implemented in the following manner.
The first thing to do is to create an injection-used interface.

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 Movielister implements Injectfinder {
    ...
    public void Injectfinder (Moviefinder finder) {
      this.finder = finder;
    }
    ...
}

Finally, we need to create the implementation of the dependent Moviefinder based on different frameworks.

3. Finally

Dependency injection reduces the coupling between dependent and dependent types, does not need to modify dependency type implementations when modifying a dependent type implementation, and, for test of dependent types, it is more convenient to use mocking object instead of the original dependent type to achieve the purpose of unit testing independent of dependent objects.

Finally, it is important to note that dependency injection is just a way of implementing control inversion. There is also a common implementation of control inversion called dependency lookups. Reference Inversion of Control Containers and the Dependency injection pattern how to Think on the "new" Operator with Respect to Unit Testing Dependency Injection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.