Unknown Date

Dependency Inversion Principle (DIP)

Definition:

High-level modules should not depend on low-level modules; both should depend on abstractions. Additionally, abstractions should not depend on details; details should depend on abstractions.

Explanation:

The Dependency Inversion Principle encourages decoupling high-level and low-level modules by introducing abstraction layers, typically through interfaces or abstract classes. This allows high-level modules to remain unaffected by changes in low-level modules, enhancing flexibility and facilitating easier maintenance and testing.

Example:

Consider a LightBulb class directly used by a Switch class. To adhere to DIP, introduce an abstraction that both depend on.

# Violates DIP
class LightBulb:
    def turn_on(self):
        pass
    
    def turn_off(self):
        pass

class Switch:
    def __init__(self, bulb: LightBulb):
        self.bulb = bulb
    
    def operate(self, on: bool):
        if on:
            self.bulb.turn_on()
        else:
            self.bulb.turn_off()

# Adheres to DIP by introducing an abstraction
from abc import ABC, abstractmethod

class Switchable(ABC):
    @abstractmethod
    def turn_on(self):
        pass
    
    @abstractmethod
    def turn_off(self):
        pass

class LightBulb(Switchable):
    def turn_on(self):
        # Turn on the bulb
        pass
    
    def turn_off(self):
        # Turn off the bulb
        pass

class Switch:
    def __init__(self, device: Switchable):
        self.device = device
    
    def operate(self, on: bool):
        if on:
            self.device.turn_on()
        else:
            self.device.turn_off()
← Back to Library