[JAVA] I didn't understand the meaning of injection such as DI or @Autowired, so I looked it up.

Purpose

Those who think "What is the injection of dependence !! What is DI !!" By the time I finish reading, my goal is to become "DI is a dependency injection, isn't it?"

It was when I read Mr. Toki's slide that I became "DI is an injection of dependency". https://www.slideshare.net/KouheiToki/dispring

You don't have to read my article if you read Toki's slides. But I want you to read it, so please keep in touch with me for a while! !!

The part that could not be organized about DI

I first came into contact with DI when I used Spring's @Autowired. It was about half a year after I changed jobs. Until now, Java reference books have stated that "new should be done when using classes", but I was very confused because I didn't do that at all in the field.

Sample.java


@Autowired
Test test;
test.sayHello();

Because it works on, it didn't make sense to me at the time when I didn't even know the interface or its implementation. Is it moving by magic! !! When

So, if you look up @Autowired, which I don't understand, on the site or in reference books

** Dependency Injection **

Totally incomprehensible! !! !! I was very annoyed by this word. And even if I read the implementation using explanations and examples, it didn't come to my mind. Just read Mr. Toki's slide

DI → just a design pattern DI container → Framework that realizes DI (@Autowired is this story)

Knowing that, what I read in the reference book was organized within me. So what you need to know before looking at @Autowired is DI. To know what DI is

** 1. What is DI D ** ** 2. What's wrong with dependence ** ** 3. What is DI I **

I would like to write in the order of.

1. What is DI D?

For example, suppose you have an attendance monitoring program. The attendance monitoring program will contact A and tell him where he is if he is weak in the morning and does not go to work during the opening hours.

Main.java


public class Main {
    public static void main(String[] args) {
        //Set A's information
        SomeOne aKum = new Akun();
        aKum.setName("Mr. A");
        aKum.setNumber(09095171835);
        AttendanceMonitor monitor = new AttendanceMonitor();
        // monitor.tellWhereHeIs(aKum)Will tell you where A is.
        String akumsPlace = monitor.tellWhereHeIs(aKum); 
    }
}

AttendanceMonitor.java


class AttendanceMonitor {
    private Call call;//A class to make a phone call to confirm your whereabouts
    AttendanceMonitor() {
        //Part D of this theme
        call = new Call();
    }
    public String tellWhereHeIs(Latecomer latecomer) {
        return call.findOnesPlace(latecomer);
    }
}

In this example, the AttendanceMonitor class depends on the Call class. What is addiction in the first place? I didn't write it clearly in Japanese Wikipedia, so from English Wikipedia

A "dependency" is an object that can be used, for example as a service.

I think that dependency means something like ** object ** used as a service (is it a processing meaning?). Dependencies refer to objects. In this case, the AttendanceMonitor class uses the Call class, so The new Call class in the AttendanceMonitor class is "dependency".

It is said that it depends on the state that AttendanceMonitor cannot be generated without new Call class.

2. What's wrong with dependence

Dependent objects are not flexible in responding to changes.

In this example, Mr. A is contacted by phone. However, it is troublesome to call every time. It also costs a phone bill. So let's say you change to line contact.

In that case, if it depends on the Call class, you need to change it as follows.

AttendanceMonitor.java


class AttendanceMonitor {
    //private Call call;//Deleted because it was changed to Line
    private Line line;
    AttendanceMonitor() {
        //call = new Call();//Deleted because it was changed to Line
        line = new Line ();    
    }
    public String tellWhereHeIs(Latecomer latecomer) {
        // String onesPlace = call.findOnesPlace(latecomer);//Deleted because it was changed to Line
        return line.findOnesPlace(latecomer);
    }
}

I changed the Attendance Monitor in 3 places even though I just changed the contact method. Since this is an example, there are three places, but there may be more changes in the code used in the actual business. Now that we've fixed the AttendanceMonitor, we also need to unit test the AttendanceMonitor.

Dependence makes you inflexible in responding to changes.

The solution is injection. In other words, it is the I (Injection) part of DI.

3. What is DI I?

In this example, the ** AttendanceMonitor class depends on the Call class. ** ** If I wanted to change the way to contact Mr. A to Line etc., I had to modify the AttendanceMonitor class. The inflexibility to this change is ** Implement the interface and inject the instance to solve it **

AttendanceMonitor.java


class AttendanceMonitor {
    //private Line line; 
    private Contact contact;//Contact interface
    AttendanceMonitor(Contact contact) {
        //line = new Line (); //Do not instantiate dependent classes with new
        //Caller(Main class)Use the instance passed from
        contact = contact; 
    }
    public String tellWhereHeIs(Latecomer latecomer) {
        return contact.findOnesPlace(latecomer);
    }
}

Line.java


public class Line implements Contact {
    @Override 
    public String findOnesPlace(Latecomer latecomer){
       //Body treatment that contacts the person who is late on the line and returns the whereabouts
    }
}

Contact.java


public interface Contact{
    public String findOnesPlace(Latecomer latecomer);
}

AttendanceMonitor no longer depends on the class of contact means by injecting classes externally. I haven't created a new instance in AttendanceMonitor.

The external class is the Main class in this example.

Main.java


public class Main {
    public static void main(String[] args) {
        //Set A's information
        SomeOne aKum = new Akun();
        aKum.setName("Mr. A");
        aKum.setNumber(09095171835);
        //Instantiate on the user side and inject dependencies! !! !!
        Line line = new Line(); 
        AttendanceMonitor monitor = new AttendanceMonitor(line);
        monitor.tellWhereHeIs(aKum); 
    }
}

AttendanceMonitor becomes loosely coupled by passing an instance of how to contact Mr. A from the Main class. Then, whether you want to find Mr. A with a drone in the future or with some more convenient contact method, the change will be only for the class you use.

Thanks to dependency injection.

DI is a dependency injection (summary)

DI was a design pattern. It says that it depends on the part that is new in the class, and in order to eliminate it, the caller passes the class that you want to new. If you can understand this

Sample.java


@Autowired
Test test;
test.sayHello();

I also understood. DI container is a framework that realizes various things such as DI (AOP etc.?). There's something weird about @Autowired, but all you're actually doing is passing the Test class to the Sample class in the constructor! !! (I don't think it's just that)

After all, "DI is a dependency injection, isn't it?"

Recommended Posts

I didn't understand the meaning of injection such as DI or @Autowired, so I looked it up.
[Action View :: Missing Template] I didn't understand the meaning of the error statement, so I looked it up.
I didn't understand the topological sort, so I looked it up and implemented it in BFS, and then tried to solve the AtCoder problem.
I did Docker construction of rails + postgresql as official, but it didn't work, so I fixed some
I don't understand the devise_parameter_sanitizer method, so I'll output it here.
I used it without knowing the O / R mapping of rails, so I checked it.