Dependency inversion principle

By Karol Bocian | February 24, 2020

Dependency inversion principle

High-level modules should not depend on low-level modules, but the dependence should result from abstraction.

All high level modules should be connected with low-level modules by abstraction. Abstractions should not depend on details, but details should depend on abstraction.

Helpful to comply with this rule is to follow these rules:
  • Every variable in class should be a reference to abstraction.
  • All class should implement an abstraction.
  • No child class overrides methods from the base class.
  • Setting variables should be making by factory pattern or dependency injection.

This rule can be applied to methods, functions, classes, modules and packages.

Advantages

  • Easier component replacement.
  • Easier changes to the software.
  • Easier reuse of components.
  • Easier testing.

Disadvantages

  • The need to use interfaces and abstract classes.
  • Labor consumption in creating stable abstractions.
  • The need to use factories or dependency injection.

Examples

  • The report generation class (high level) uses the class that logs information about exceptions in the application (low level). He must convey, among others path to the log folder. Changing the class logging into the file to the class logging into the database will force a change in the class generating the report because you will have to pass other data to the constructor of the logging class.
    Copier class using the Reader class and the Writer class. If we have used classes, and we want to change the way of saving (from printing to a printer, to generating pdf), we will also have to change the Copier class or create a new class Copier PDF. If the Copier class had references to the IWrite interfaces, then it would be enough to inject an appropriate implementation of the IWriter to achieve our goal.

All posts from mini project: Learn SOLID and OOP principles:

Sources

Main image

Materials