The best definition of dependency injection that I found online is by James Shore:
"Dependency injection means giving an object its instance variables. Really. That's it."
In the example above, there are unnecessary dependencies.
An instance of a Computer must use an Nvidia graphics card. What if my future computers use AMD graphics cards? This will require me to change the name of the graphics card I use in my Computer code. Making instances of Computer depend on a certain graphics card also reduces the code’s reusability.
To fix this, we’ll use dependency injection.
See how simple the change was? All I did was, as James Shore would put it, give an instance
of Computer its
@graphics_card instance variable. Now I can swap out Nvidia graphics
cards with AMD graphics cards easily.
Because of duck typing, Computer’s
display_graphics instance method doesn’t care if
the graphics card is an instance of Nvidia::GeForce or AMD::Radeon. As long as the object
display_graphics messages, any will do.
Furthermore, dependency injection allows me to test the graphics card that my computer uses.
For example, when an instance of Computer calls
display_graphics, I want to ensure
@graphics_card and not some integrated graphics card.