Dependency Inversion Principle (DIP)
The Dependency Inversion Principle states that high level modules should not depend on low-level modules - instead, they only should depend on an abstraction.
Abstract classes should not depend on concrete classes.
Example 1: Microsoft Word
Here, the word counter relies on some sort of keyboard input. This breaks dependency inversion principle because counting words is “high level”, getting input “low-level”.
Rather, want to rely on some sort of generic input interface, and we can apply Strategy Pattern.
Example 2: Timer with Lights/Bell that goes off
Apply dependency inversion once => timer should no longer rely directly on Bell.
Apply dependency inversion again => Abstract Responder should not depend on the concrete timer.
This is simply the Observer Pattern - where Source
s are subjects, Responder
s are observers.
Could apply dependency inversion again → introduce another layer of abstraction between timer and bell / lights - but at some point, usefulness runs out. Too many layers of abstraction creates needless complexity.