SOLID - Dependency Inversion Principle (DIP)

SOLID - Dependency Inversion Principle (DIP)

Dependency Inversion Principle emphasizes decoupling and abstraction in software systems by defining guidelines for dependency relationships between modules or classes.

High-level modules should not depend on low-level modules. Both should depend on abstractions.

In simpler terms, DIP encourages the use of interfaces or abstract classes to define contracts and dependencies between modules, rather than depending on concrete implementations. This allows for flexibility, extensibility, and easier maintenance of the codebase.

To adhere to DIP, the following practices are recommended:

  • Programming to interfaces or abstract classes rather than concrete implementations.
  • Using dependency injection to provide dependencies to classes rather than instantiating them directly.
  • Employing dependency inversion frameworks or inversion of control containers to manage object dependencies.

DIP and Multiple Inheritance

This is a special case of Dependency Inversion Principle (DIP) with multiple inheritance in Python.

class MyInterface(ABC):
    @abstractmethod
    def method(self):
        pass

class MyBaseClass:
    def base_method(self):
        print("Base method")

class MyImplementation(MyInterface, MyBaseClass):
    def method(self):
        print("Implementation of method")        

class MyClient:
    def __init__(self, interface_obj: MyInterface):
        self.interface_obj = interface_obj

    def perform_operation(self):
        self.interface_obj.method()

my_interface_impl = MyImplementation()
client = MyClient(my_interface_impl)
client.perform_operation()

In the provided example, where MyImplementation inherits from both MyInterface and MyBaseClass, and the methods of MyBaseClass are only used internally within MyImplementation, it can be acceptable to use them.

Since MyBaseClass is not exposed externally and its methods are used only within the implementation details of MyImplementation, it does not violate the Dependency Inversion Principle (DIP). The DIP mainly focuses on the dependencies of higher-level modules or objects, ensuring that they depend on abstractions rather than concrete implementations. As long as the external interface of MyImplementation adheres to MyInterface, it can utilize internal implementation details as needed.

However, it's still important to be cautious and ensure that the internal usage of MyBaseClass methods aligns with the design and intent of your code. If there is a possibility that the internal usage might evolve to be part of the public interface or if the dependency becomes more significant, it may be worth reconsidering the design to further decouple the dependencies and promote cleaner abstraction boundaries.

You can see a working code example here:

https://github.com/robson-koji/FullTextSearch-Validator/blob/main/full_text_search_validator.py

Popular posts from this blog

Atom - Jupyter / Hydrogen

Design Patterns

Robson Koji Moriya disambiguation name