In past couple of days, I have read about quite a lot about dependency injection/inversion of control/inversion of dependency. I think that, now my understa
Think of the work you need to invoke, and how far away that is from where you are currently coding. There is a spectrum there; your position on it represents the amount of work you need to do to invoke that functionality.
Abstractions move that position closer to the code you are writing. For example, if you have to call a web service, you can either 1) write the calling code directly where you need to use it, or 2) put those details behind an abstraction (such as an interface).
In this case, #1 puts you closer to the web service on the spectrum, while #2 keeps you closer to your work. Abstraction can be said to be a measure of how far you have to stretch your mind to comprehend the work you need done.
What this means is that every piece of work can be abstracted so that it is "closer" to the code using it. By having both sides of an operation depend upon abstractions, they both become easier to understand, and neither side has to harbor knowledge of the gap between them - that is the job of the abstraction.
Wow, that was abstract.