Dependency inversion, control inversion and dependency injection are actually very simple

Posted by nicephotog on Wed, 09 Feb 2022 23:09:26 +0100

First explain the opening with the simplest (rude) sentence:

  • The upper modules should not depend on the lower modules, they should all rely on abstraction
  • Abstract should not depend on details, details should depend on abstraction

First, let's hold the following questions:

What is dependency inversion?
What is control reversal?
What is dependency injection?

To tell you the truth, when I first saw these words, I was a little confused. I didn't know what it meant. I turned to a few blogs and read them even more. I didn't realize it until I turned over a few more articles. Oh, I used it often. So record my understanding.

This article can help you clarify the meaning of these keywords and re sort out your thoughts.

What is inverted dependence?

  • The upper modules should not depend on the lower modules, they should all rely on abstraction

Beginners may want to curse when they see this explanation. And most of our students often take this sentence with them when explaining, which is indeed concise and comprehensive.

My personal understanding: dependency inversion is actually an embodiment of interface oriented development. It sounds very tall. Let me just use two pieces of code to find out:

public class Test {
    public static void main(String[] args) {
        Teacher teacher=new Teacher();
        teacher.initWang();
    }
}


/* physical education teacher */
class Teacher{
    private Wang wang;

    public void initWang(){
        wang=new Wang();
        wang.play();
    }


}

/* Favorite sports */
interface IMotion {
    void play();
}

/* student */
class Wang implements IMotion{

    @Override
    public void play() {
        System.out.println("wang I like playing football");
    }
}

In the above code, we have a Test class, a PE teacher class, a sports interface of imotion, and a student Wang

Run our Test example and print "wang likes playing football"; If we want to add another student Li now, we need to change the Teacher class at this time, such as adding another method initLi.

As follows:

/* physical education teacher */
class Teacher{
    private Wang wang;
    private Li li;

    public void initWang(){
        wang=new Wang();
        wang.play();
    }

    public void initLi(){
        li=new Li();
        li.play();
    }
}

/* student */
class Li implements IMotion{

    @Override
    public void play() {
        System.out.println("li I like playing basketball");
    }
}

I know some students may want to scold now. Is this blogger a fool? Can't he directly use the interface object. Don't worry, let's transition slowly.

Dependent inverted version

public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.play();
    }
}


/* physical education teacher */
class Teacher {
    private IMotion iMotionWang;
    private IMotion iMotionLi;
    public Teacher(){
        iMotionLi=new Li();
        iMotionWang=new Wang();
    }

    public void play() {
        iMotionWang.play();
        iMotionLi.play();
    }

}

Some students may be about to shout? Isn't that what I often write? It's called dependency inversion?

Yes, you're right. Although there are still some problems in this demo (such as who's okay and the new interface), it already has the idea of dependency inversion. In the previous version, we have been using new as a concrete instance to operate for specific students, but now we are dealing with its abstract class, and our thinking has actually changed.

Some students may ask that the abstraction should not depend on the details. The details should depend on the abstraction. How do you explain it?

Think about it carefully. Is this the idea of the interface we just wrote? The Teacher class needs the behavior of sports that students like. In the form of interface, no matter how many students we add, it will not affect the Teacher class (don't pay attention to multiple new).

Next, let's look at the second feature, control inversion:

Let's change the code as follows:

public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher(new Wang());
        teacher.play();
    }
}


/* physical education teacher */
class Teacher {
    private IMotion iMotion;

    public Teacher(IMotion iMotion) {
        this.iMotion = iMotion;
    }

    public void play() {
        iMotion.play();
    }

}

Most students must shout again. Isn't this the version when I often write code? This is control inversion? Who are you lying to?

No problem. This is really a reversal of control. Compared with the previous version, we handed over the step of new to the specific test class instead of the Teacher class. In this way, no matter how many student classes are added in the future, the Teacher does not need to be changed.

Let's take another look at dependency injection:

In fact, we have just done dependency injection. For example, we pass in specific objects through constructors. Of course, it can also be passed through the set method;

As follows:

public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.setiMotion(new Wang());
        teacher.play();
    }
}


/* physical education teacher */
class Teacher {
    private IMotion iMotion;

    public void setiMotion(IMotion iMotion) {
        this.iMotion = iMotion;
    }

    public void play() {
        iMotion.play();
    }

}

After reading the above, do you think it's very simple? In fact, it's nothing to rely on inversion. Yes, many seemingly profound nouns will feel awesome if we don't understand them. In fact, as long as we follow the design mode, these so-called nouns are nothing. Although the above demo looks very simple, the focus should not be on the defect demo, but on the code transition. Now we look at these operations and think they are very simple. That's because we have written too much business code and design patterns are often involved, so we don't think it's difficult.

If you are a new student, I suggest you carefully feel the transition process and experience the happiness of interface oriented development.

Of course, the above is only my personal understanding. If there is any deviation, I hope you will give me your advice.