I'm not able to figure out the difference between the Dependency Inversion Principle (one of the S.O.L.I.D principles) and the general 'Code to Interfaces' or Separated Interface pattern. All of them advocate creation of a layer of abstraction to decouple the lower level and the higher level modules.

The DI principle envisages creation of interfaces to interact between the higher and lower level modules, but also insists that the interfaces must be a part of the higher level package.
Why should this be a part of higher level and not lower level ? It's is the lower level that's exposing its behavior, so shouldn't the decoupling interfaces be a part of lower level? What if there are multiple higher level modules depending upon the same lower level?

Or else,
Why not make a separate package in which to place all the interface, which then can be used by both higher level and lower level? (This is envisaged by the Separated Interfaces pattern.)

My dilemma is, I am not able to figure out the relative use and benefits or each of them.

Please do not quote article by Derek Greer or Robert Martin. I have read those articles, but confusion still persists.

3

There are 3 answers

5
Wand Maker On

Dependency Inversion is concept that is building block for Dependency Injection frameworks such as Spring, Guice, etc. What it says is that a component should not look up its dependency but should be injected its dependency from outside. A dependency for a component can be an interface or another class. When dependency is an interface, then the component is flexible to work with variety of implementations.

Let's take an example: Let's say someone is writing a component which needs to make some service calls. If the component developer thinks that the service calls has to be always made using HTTP, then, she will make a HTTP Client a dependency. Now, this restricts the components utility to only be able to call HTTP-based services. However, same developer could have created an interface, lets say - GenericExternalServiceInvoker, and have implemented two implementations - one which made use of HTTP and another that made use of some kind of queuing system like ActiveMQ. Use of interface enabled the component developer to create components that are useful in much broader way.

In the above example, we assumed that DI was in place. Because the dependency was being injected from outside. Component developer could have made another design choice and could have instantiated HTTP Client in the code, and thus making it difficult for users of the component to change its behavior, if need had arisen, to use something else other than HTTP.

So, in summary, one should use DI so that component does not depend on its dependency in hard-wired manner. By making component's dependency an interface, a further flexibility gets built into component. The second principle, Code to interfaces, is guiding factor for the developer to have picked an interface as dependency rather than a concrete class.

2
Ivaylo Slavov On

I suppose you meant what is the difference between Dependency Injection and programming to interfaces

Programming to Interfaces

Programming to interfaces is a practice in software development, where different objects interact with each other via public interfaces. This allows for a greater flexibility, as one may switch easily from one interface implementation to another, with minimal changes to the codebase, and may even avoid recompilation of the code.

Dependency Injection

Dependency injection is a mechanism that allows object instances to be created by the framework rather than the developer. In most cases, an object may require some additional objects (called dependencies) to already exist and be passed in the constructor of the current object, or to a property of that object, in order for it to be usable. Dependency injection is a mechanism that allows a framework to provide and set these when constructing the required object (injecting them). Usually, the framework knows what to do based on external configuration, or code inspection.
The dependency injection paradigm relies on the programming to interfaces practice (that is why I described it first), as the dependencies are usually exposed via their public interfaces. Thus, different implementations can be used based only on configuration changes. This would enable easily using a mock setup of objects when testing certain aspects of the application.

Usually, dependency injection is referred to an inversion of control mechanism, as it causes the framework (meaning the application code) to deal with object creation rather than manual instantiation (done by the developer).

as per aknon's comment:

Is dependency injection same as dependency inversion?

Not necessarily. Dependency inversion might also be called the refactoring process of inverting the dependencies between two objects. For instance class A may depend on class B prior refactoring, and after that you may have class B to depend on class A instead, thus inverting their dependencies. Dependency injection is a mechanism provide dependencies without writing code for that explicitly.

Update

For more information on the term dependency inversion I recommend you to read this article from Rich Newman. It is part of series of articles addressing the Microsoft Smart Client Software Factory technology (now an outdated one), but the article is neutral enough and can stand by itself.


See also:

2
Raffaele On

Programming againts interfaces is usually required for complex dependency injection. I don't think that putting the APIs in a separate module, or just in a different package, or side-by-side the implementations can be right or wrong in principle. It depends: most projects I've seen bundle interfaces and implementations together, but there are times where the api binaries are even shipped in a different archive, like servlet-api.jar or logging-api.jar.

In fact I don't see any value in comparing the twos on such a detail. After some time I decided that common sense is the only principle that always applies, and when reading about a methodology/pattern/whatever one should take into account that it's author sells books, speaks in conferences and in general makes a business out of it. That's not to say these readings are useless, quite the opposite: they are a fundamental way of learning from others' successes and failures. But the arguments should be taken with a grain of salt, because maybe the solution doesn't fit well in a particular project.

The only "bible" in this field are things that can be somehow measured, like data structures and algorithms, and specifications. I wouldn't bother who is more right between uncle Bob and Martin Fowler about where to put your interfaces: put it wherever you are comfortable with and in a place where it works for you. After some time, if you made the wrong decision, you'll always be able to refactor and move things around.