Dependency inversion principle
This principle mainly state that, a module should "Depend upon abstractions, [not] concretions.", and more precisely:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
Code example
The example above is bad because the object is created within the function and you add an useless if/else statement that will be harder to maintain (more difficult to handle bug, more difficult to add new object, ...). It is way more simple / maintenable to make your function depends on an external object and to make this object not a concretion but an abstraction / an interface. Now, the barks function depends ont he interface and not the object concretion. the function barks may use any Dog object and we are sur that every Dog object will have a bark method, because of the interface. Why do we call this principle the "dependency inversion principle" , because now, the dependency goes to the client. The client (i.e. the barks function) is the one that want to produce the barks sound. The client is some piece of code that is going to use bark function. The client doesn't know exactly what is going to barks(), but know that the object will have a bark() method.References
- https://en.wikipedia.org/wiki/Dependency_inversion_principle
- "Clean Architecture: A Craftsman's Guide to Software Structure and Design" by Robert Martin
- https://stackoverflow.com/questions/61358683/dependency-inversion-in-python