Depend on abstractions and not on modules with the Dependency Inversion Principle

Image for post
Image for post

This article, the fifth of the 5-part article on S.O.L.I.D design principles, is about the “D,” Dependency Inversion principle made famous by Robert C. Martin (Uncle Bob)in his paper, https://web.archive.org/web/20150924054349/http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf.

SSingle-responsibility principle

OOpen-closed principle

LLiskov substitution principle

IInterface segregation principle

D — Dependency Inversion Principle

Definitions

Robert C Martin defines DIP as

Depend upon Abstractions. Do not depend upon concretions

Popular definitions

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B.
Abstractions should not depend upon details. Details should depend upon abstractions.

Dependency

In our previous discussions with OCP, we have seen that the goal of an OO architecture is to reduce the amount of change to a module, preferably have no change. A primary source of change is a concrete implementation of a module, i.e a particular type or A specific implementation. Usually, a higher-level module will have dependencies on lower level implementations without really any need to know about it.

Image for post
Image for post

In the example above, a high-level print module prints the content of a document or some text to the Console. The print module is thus dependent on the Console module.

Dependencies with concrete implementations

The problem with concrete implementation is they can change, they are volatile. For e.x. in the above case, the client decides to have the ability to print to a printer as well. Or maybe they want to print the content to a PDF module. Thus we can see concrete implementations reflect the change in the real world and are always susceptible to change. So dependencies arising out of concrete implementations are volatile as well, leading to a lot of changes in the client

Depend upon Abstractions. Do not depend upon concretions

DIP aims to fix this dependency problem with modules wherein High-level modules depend on concrete low-level modules. DIP proposes that

High-level modules instead of depending on low-level modules should depend on abstractions.

The beauty with abstraction is it enables a designer to hide the implementation details. Abstractions define the contract which a high-level module is assured of. But at the same time, it is not concerned with how it’s implemented thereby removing the dependency between the high-level module and low-level module, thus preventing any fallout of change to the high-level module

Image for post
Image for post

Now we can see, the high-level module print is no longer dependent on a low-level module like Console or Printer. It’s dependent on the abstraction PrintOutput. Moreover, the actual printing details are now dependent on the abstraction Print. Depending on the output, i.e console, printer, pdf, remote printer, etc the print details will vary. Hence the Dependency has inverted from the details to the abstraction. Newer implementation details can easily be added as a dependency to the client by hiding its implementation behind the abstraction

Dependency Inversion Principle makes the assumption that everything that is concrete can change. This might not always be true. As a designer of a system, it is very essential to determine if the concerned class can change. If it's definite that the class can change, it is better to hide the details or implementation of the class behind abstraction and have the clients depend on that

A leading mobile app development company specialising on iPhone, Android, Cloud solutions, User Experience and UI Design.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store