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.
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.