SOLID Design Principles

0% completed

Previous
Next
Refactoring Code to Follow DIP

In the previous lesson, we saw how a tightly coupled design violates the Dependency Inversion Principle (DIP). To follow DIP, we need to introduce abstractions and make both high-level and low-level modules depend on them, rather than depending directly on each other.

Step 1: Introduce an Abstraction

We’ll start by creating an abstraction for sending notifications. This abstraction will be an interface called NotificationSender, which defines a method for sending notifications.

Python3
Python3
. . . .

Step 2: Implement Low-Level Modules Based on the Abstraction

Next, we’ll implement different notification services, such as EmailService and SMSService, that depend on the NotificationSender interface.

Python3
Python3
. . . .

Now, the low-level modules (EmailService and SMSService) implement the NotificationSender interface, following the principle that details should depend on abstractions.

Step 3: Modify the High-Level Module to Depend on the Abstraction

We’ll refactor the NotificationService to depend on the NotificationSender interface instead of directly on a specific implementation. This will decouple the high-level module from the low-level details.

Python3
Python3
. . . .

Step 4: Test the Refactored Design

Image

Now, we can easily switch between different implementations of NotificationSender (e.g., EmailService and SMSService) without modifying the NotificationService.

Python3
Python3

. . . .

Explanation

  1. NotificationSender Interface: Defines a general send() method for sending notifications.
  2. EmailService and SMSService Classes: Implement the NotificationSender interface, providing specific implementations for sending emails and SMS.
  3. NotificationService Class: Depends on the NotificationSender interface, making it flexible and decoupled from specific implementations.
  4. Main Class: Demonstrates using the NotificationService with both EmailService and SMSService.

How This Solution Follows DIP

  • High-Level Module Depends on Abstraction: The NotificationService class depends on the NotificationSender interface, not on specific implementations.
  • Low-Level Modules Depend on Abstraction: Both EmailService and SMSService implement the NotificationSender interface, allowing them to follow a common contract.
  • Flexible and Extensible: New notification types can be added by implementing the NotificationSender interface without modifying the existing NotificationService.

.....

.....

.....

Like the course? Get enrolled and start learning!
Previous
Next