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
from dataclasses import dataclass
from abc import abstractmethod
from typing import List
# Bad implementation
@dataclass
class Dog():
size: str
@abstractmethod
def bark(self):
pass
@dataclass
class BigDog(Dog):
size: str = "big"
@abstractmethod
def bark(self):
print("WOF WOF")
@dataclass
class SmallDog(Dog):
size: str = "small"
@abstractmethod
def bark(self):
print("wof wof")
def barks(size_of_dog: str):
if size_of_dog == "small":
dog = SmallDog()
dog.bark()
elif size_of_dog == "big":
dog = BigDog()
dog.bark()
else:
raise NotImplementedError
barks("big")
# Good implementation
@dataclass
class Dog():
size: str
@abstractmethod
def bark(self):
pass
@dataclass
class BigDog(Dog):
size: str = "big"
@abstractmethod
def bark(self):
print("WOF WOF")
@dataclass
class SmallDog(Dog):
size: str = "small"
@abstractmethod
def bark(self):
print("wof wof")
def barks(dog: Dog):
dog.bark()
barks(BigDog())
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