DEV Community

Cover image for SOLID Design Principles: Learn the Dependency Inversion Principle
Alireza Shabani
Alireza Shabani

Posted on

SOLID Design Principles: Learn the Dependency Inversion Principle

πŸ‘‹ Hey there, fellow software enthusiasts!

I'm Revisto, a passionate software engineer πŸ‘¨β€πŸ’», and I want to dive into the exciting world of SOLID principles.

SOLID is a set of rules and principles that help us create maintainable, reusable, and flexible software designs. These principles guide us in building software that can adapt and grow as our projects evolve. Today, we will focus on the third principle of SOLID.

The Dependency Inversion Principle (DIP):

✨ Now, let's shine a light on the Dependency Inversion Principle (DIP). This principle focuses on managing dependencies between classes, aiming to create software systems that are flexible, maintainable, and extensible.

πŸ’‘ The core idea of the DIP can be summarized as "depend on abstractions, not on concretions." In other words, classes should rely on interfaces or abstract classes rather than concrete implementations. By doing so, we invert the traditional dependency flow.

Robert C. Martin, one of the proponents of SOLID principles, defines the Dependency Inversion Principle in two parts:

  • High-level modules should not depend on low-level modules. Both should depend on abstractions. This means that the modules at a higher level of abstraction should not rely on the lower-level details. Instead, they should depend on abstract interfaces or classes.

  • Abstractions should not depend on details. Details should depend on abstractions. This emphasizes that the abstract interface or class should not be influenced by the specific implementation details. It should provide a contract that the concrete implementations adhere to.

πŸ“” Common Example:

Understanding the Scenario:
Imagine we have a Logger class that is responsible for writing log messages to a file. We also have a Calculator class that performs arithmetic operations and uses the Logger class to log information about those operations.

class Logger:
    def log(self, message):
        with open('log.txt', 'a') as f:
            f.write(message + '\n')

class Calculator:

    def __init__(self):
        self.logger = Logger()

    def add(self, x, y):
        result = x + y
        self.logger.log(f"Added {x} and {y}, result = {result}")
        return result
Enter fullscreen mode Exit fullscreen mode

❌ In the original implementation, the Calculator class directly creates an instance of the Logger class within its constructor. This creates a strong dependency between the two classes, making it difficult to modify or replace the Logger implementation in the future.

from abc import ABC, abstractmethod

class LoggerInterface(ABC):
    @abstractmethod
    def log(self, message):
        pass

class Logger(LoggerInterface):
    def log(self, message):
        with open('log.txt', 'a') as f:
            f.write(message + '\n')

class Calculator:
    def __init__(self, logger: LoggerInterface):
        self.logger = logger

    def add(self, x, y):
        result = x + y
        self.logger.log(f"Added {x} and {y}, result = {result}")
        return result
Enter fullscreen mode Exit fullscreen mode

To adhere to the Dependency Inversion Principle, we can introduce an interface, LoggerInterface, which defines the log method. The Logger class then implements this interface, ensuring it adheres to the contract defined by the interface.

Image description

By adhering to the Dependency Inversion Principle, we achieve loose coupling between classes, making our software more flexible and easier to maintain. It also enhances code reusability and allows for more straightforward testing and future modifications.

πŸš€ Stay tuned for more articles where we'll explore other exciting programming topics and delve into the exciting world of software engineering.

Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on Linked In and Github.

Happy coding!

Top comments (0)