Now that you’ve seen dependencies, imagine a codebase full of these dependent classes. Now imagine that the dependencies ALSO have dependencies. One change in one dependency could break dozens of other classes. It gets messy very quickly.
In the early 2000s, the influential developers and authors Robert C. Martin and Martin Fowler came up with a strategy to resolve these problems. They generalized their strategy into two principles.
The first principle is the Dependency Inversion Principle and it states:
- High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).
- Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
In our previous example, the Trainer
class depended on the LoudSpeaker
class. The Dependency Inversion Principle (DIP) states that the Trainer
class should depend on some ISpeaker
interface. LoudSpeaker
should be designed to implement that interface.
The second principle is the Inversion of Control Principle and it states:
- Methods defined by the user should be called from within the framework itself, rather than from the user’s application code
This is also known as the “Hollywood Principle”: Don’t call us, we’ll call you.
In our previous example, the Trainer
class should not instantiate another class. It may declare a certain dependency and some other part of the program will provide and manage that dependency.
Instructions
Take a look at these images, which demonstrate the two concepts DIP (Dependency Inversion Principle) and IoC (Inversion of Control).
The “Before” architecture suffers from dependency problems. In the “After” architecture, neither component depends on the other. They both depend on an abstraction (interface).