Dependency Inversion Principle: DIP
Introduction
Dependency Inversion Principle is the last principle of SOLID presented by Uncle Bob.
They are :
- Single Responsibility Principle
- Open-Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
In this post, I will focus on DIP, and I will explain the other principles in future articles.
Definition
Uncle Bob defines the principle as:
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.
let’s explain both levels:
High-level modules are those that contain your business code and application features.
Lower-level modules are those that contain implementations based on storage, communication or external servers (e.g., database).
The obvious advantage of DIP is that you can switch implementations by simply modifying a line of code in your configuration.
To implement the DIP you should:
- Write the interfaces for low-level implementation that high-level classes will need, these interfaces are part of the high level.
- Make high-level classes dependent on these interfaces, instead of making them dependent on low-level concrete classes.
Example
Consider for example a notification system using Email and SMS.
Look at the code on top. We have two Email and Sms classes that send a notice to a user.
To implement this, let’s set up a notification class.
Now, If we want to add another type of notification, we must change this class (OCP violation). Or if we change one of the classes (Email, Sms) we risk changing our notification class because we depend on implementation and not on abstraction.
So to avoid violating the DIP, let’s create the interface IMessage that represents our Abstraction, and let’s make the two classes Sms & Email implement this interface.
After that let’s make out Notification class depend on IMessage abstraction.
Now our High-level class (Notification) and Lower-level class (Sms&Email) depend both on abstraction (IMessage).
We have the ability to add any kind of notification. For this purpose, create a class for this type and implement the abstraction interface.
Conclusion
DIP allows you to reduce the coupling between your modules, and makes high-level and low-level modules dependent on abstraction.
DIP goes with the OCP and LSP principles. You need to make sure you follow those principles. It’s the last story in the Solid series.
Thank you for reading this quick post. If you like the content feel free to follow me on my social media profiles. Thank you.
Twitter: https://twitter.com/HBenkachoud
Linkedin: https://www.linkedin.com/in/hicham-benkachoud/