Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the real use case of dependency injection? [duplicate]

I understand dependency injection but what i really don't understand is, what is the use of dependency injection.

As it is mentioned here this helps in testing your code easily (It's a very useful technique for testing, since it allows dependencies to be mocked or stubbed out.) , but now a days there are lot of mocking frameworks like Mockito, powermockito which can do these jobs quite well than why dependency injection?

It would be great if somebody could explain with code.

Thanks in advance.

like image 290
Trying Avatar asked Jul 19 '14 09:07

Trying


2 Answers

The primary uses for DI as a technique are :

It leads to a code that is easier to test ( using Mocking ). This means that in order to use mocking frameworks ( Mockito etc ) , you should be using more of DI. If you dont use DI and write code that instantiates objects directly - then practically you cannot use Mockito to mock your dependencies.

Lets say you write code to play an Orchestra. Your main class depends upon so many other classes ( that other people wrote perhaps ).

Lets say you wrote this :

public class Orchestra {
  private Drums drum;
  private Violin violin;
  private Guitar guitar;

public Orchestra() {
    drum = new Drum();
    violin = new Violin();
    guitar = new Guitar();
}

public Music play(){
    // use above in some way to run your orchestra
    // start with violin 
    // add some guitar and then bring in the drums too
}

}

Now you want to ensure that your logic in play works accurately. When you run your class you see the music is not what you are expecting. ( maybe the drummming is starting right at the start ). You want to test the logic of your code play. How would you do that here ? You have no control over your dependencies. You dont know if there was an issue with code of Drum or your own logic in play().

You would want to mock out Drum here. But you cannot do that easily. Because your code does not use DI. Its instantiating the Drum directly inside.

Now lets use DI and see how it helps.

public class Orchestra {
    private Drums drum;
    private Violin violin;
    private Guitar guitar;

    public Orchestra(Drums d,Violin v, Guitar g ) {
        drum = d;
        violin = v;
        guitar = g;
    }

    public Music play(){
        // use above in some way to run your orchestra
    }

}

With this code , it becomes easy to mock out Drum in your test.

class TestOrchestra {

    public void testPlay(){
        Drum mockDrum = mock(Drum.class);
        Violin mockViolin = mock(Violin.class);
        Guitar mockGuitar = mock(Guitar.class);
        // add mock behaviour to above , here you control precisely what these dependencies will do inside your code

        Orchestra orch = new Orchestra(mockDrum, mockViolin,mockGuitar);
        // now play and test your logic

    }

}

The second advantage of using DI is that it helps vary implementations of bigger parts of your program without needing to go through your entire code.

Again - with reference to above , lets say you have been playing your orchestra using a particular type of guitar ( which is instantiated internally by your code).

Now you want to change to an brand new electric guitar.Without DI , you would have to open up your Orchestra class , check where you create the Guitar and change that line of code. You would have to ensure that other parts of your code are not changed inadvertently and test entire Orchestra to make sure things work correctly.

With DI , you could avoid all this. You just inject the new Guitar object into your constructor. Thats it. Because you have tested the new Guitar object on its own ( and it fulfills the contract of the interface Guitar - you can be rest assured that your Orchestra code is not broken by injecting this new Guitar. Thats quite a better improving your orchestra.

like image 153
Bhaskar Avatar answered Nov 14 '22 23:11

Bhaskar


Dependency injection is not an alternative to mocking frameworks. It's a requirement. If you have hard dependencies, it's a lot harder to mock the dependencies and therefore test the code.

DI also allows you to have more loosely coupled code. Classes can use other classes simply by having them injected, instead of knowing how to construct (or obtain an instance of) a particular class.

like image 25
Kayaman Avatar answered Nov 14 '22 23:11

Kayaman