What is Dependency Inversion Principle?
The Principle of Inversion of Dependence seeks to keep the focus of the design task in business, leaving this design independent or decoupled from the component that will perform low-level tasks that are not part of the business modeling.
In regard to this principle, instead of developing the low-level component and from it guiding the development of the high-level component, you define how will be the interaction between these components (always prioritizing the design needs of the high-level component), and hence the low-level component has to be developed respecting this definition of interaction with the high-level component.
Example - stock exchange quotes
Let’s say you need to develop a screen that shows the user, a stock exchange operator, the current listing of each asset he owns in his portfolio.
The operator wants the screen to be updated each time an asset’s quote changes, because he wants to know the total per asset and the total in the portfolio almost in real time.
The operator will pay for a real-time quotation service and your software must use this service.
You need to make a component that connects to this service, and the service will notify your component every time a role changes value, and then the component can update the wallet by promoting the screen update.
The simplest way to develop this software would be to first implement the component that connects with the service (called here Connector bag), see how it stood and then implement the update of the portfolio according to the needs of the Connector bag:
In the above solution, the high-level component depends on the low-level component.
Already the way to do this respecting the Principle of Inversion of Dependence would be you define how should be the interaction between the components, and hence both components are developed respecting this definition of interaction between them.
To this "definition of interaction" we call it "abstraction". We say that you have created a abstraction between the components.
Each component does not need to know how the other was implemented, and the focus of the design is on the business solution and not on the details of how the connection with the quotation service is made.
Interfaces
The most common way to do this in Java is by declaring an interface that determines how the portfolio update component would like to consume a quote service, and then the component that connects to the quote service implements this interface.
Before, the high-level component depended on the low-level component but now, with the above solution, the low-level component is that it depends on an interface defined by the business guidelines - we say then that there was a inversion of dependency.
Ability to replace the component in the future?
This is the most despicable reason to respect the principle.
The great benefit of the principle is to keep the focus of design on business needs rather than depending on the implementation details and needs of the lowest-level objects.
Respect for the principle should also result in more reusable components that don’t need to change just to keep up with the changes needed in another component (components can change independently of each other).
Finally, a very positive side effect of the business component no longer being coupled to the low-level component is that the low-level component can be replaced by a double (aka "mock") during automated testing.
Thank you very much, man!
– Pena Pintada