I'm reading about design patterns. I know what this principle does.
High-level and low-level classes depend on abstractions. But why we say this is inversion?
migrated from stackoverflow.com Mar 23 '13 at 9:09
This question came from our site for professional and enthusiast programmers.
Or in other words: in traditional, non-inverted control higher-level components depend on lower-level ones.
This has been demonstrated as a limitation, because high-level components lose the chance of working with more than an environment or low-level excessively specific components.
With inversion of control, the above paradigm is inverted. The high-level components are just abstract classes or interfaces and these are usually (and should be) declared in a package or assembly having no dependency on the code implementing them, and it's the implementation the code that's dependent on higher-level code (because the low-level code must implement a high-level interface or abstract class).
This is the inversion!
Quote of Bob Martin in his original article on the topic:
So as I understand, having the inversion priciple in place makes the high level policy described in terms of abstraction rather than concrete utility components. And from the point of view of the high level module the abstract policy remains stable. Any changes of the low level implementations do not force the high level module to change.
The term 'inversion' distinguishes the approach from the traditional model.
I'll put a direct example of the inversion of control.
As you can see Television is tightly coupled with the Button class, a low-level component. That means Television depends on the button class to be turned on.
Inversion of control dictates that Television must not depend on the Button class. That is: "Television must not instantiate a Button class"
The solution would be something like this:
Now Television doesnt know if its a button, a remote control or a human gesture the thing that is turning the television on. And the Button must implement the interface ISomethingThatTurnsOnTV, that is a high-level component.
So we went from:
and Television does not depends on Button anymore :D
The problem is that so-called "Dependency Inversion Principle" is poorly named and defined. While the definition was clarified by its author afterwards, the name is a total misnomer. There are no dependencies which are inverted when this principle is applied.
Traditionally, your dependencies would descend downwards in your application.
That is, you would have a high level class A, which depends on a lower level class B.
Consider a car. In traditional programming, your car object would depend on your steering wheel object, which would depend on your two front wheel objects. This means that if your wheels change, your steering wheel class needs to change, and your car class might even need to change.
Dependency inversion gets rid of these dependencies and adds two new dependencies:
This change means that we can now test the car independently from the SteeringWheel, the SteeringWheel independently from the wheels. We can also change the implementation of the Wheels or the SteeringWheel without needing to make changes to one of the parent classes.
This makes for a much more flexible architecture and helps us ensure that the other SOLID principles (particularly the SRP) are not violated.
The inversion is not a reversing of the dependencies (after all, the Wheels are not dependent on the SteeringWheel now) but is turning the dependencies 90 degrees to a new abstraction. Inversion is possibly a poor choice of word. A more descriptive choice might be "Dependency Right Angled Turn". But that's not as catchy.