To become a senior among millions of programmers!
Welcome to the final article in the SOLID series. In this article, I will talk about the Dependency Inversion Principle.
- Single Responsibility Principle
- Open / Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
1. High-level modules should not depend on low-level modules. Both should depend on the abstraction.
2. Interface (abstraction) should not depend on details, but vice versa. (Classes communicate with each other through interfaces, not through the implementation.)
Explain the principle
In the article, I often use the word module. In fact, this module can be a project, a DLL file, or a service. To make it easy to understand, you should consider each module as a class just in this article.
With conventional coding, the top-level modules will call the low-level modules. The top-level module will be dependent, and the low-level module creates the dependencies. When the low-level module changes, the top-level module must change accordingly. One change entails a series of changes, reducing the maintainability of the code.
If it follows a DIP, both the low-level and the high-level modules are dependent on a constant interface. We can easily replace, modify low-level modules without affecting the top-level modules.
To make it easy to understand, take a look at the electric lights in your home. The high-level module is the power outlet; the main interface is the round light tail; the low-level modules are the round bulb and the fluorescent bulb.
These two modules all inherit the circular chasing interface; We can easily change the 2 types of bulbs because the high-level module (power socket) only cares about the interface (round tail), does not care about the implementation (bulb or fluorescent. ).
Also, in the code, when applying a DIP, the modules are linked through the interface. To connect to the database, we need to call the Get, Save … function of the IDataAccess interface. When replacing the database, we need to change the implementation of this interface.
Code when not applied DIP:
// Cart is a high level module
public class Cart
public void Checkout (int orderId, int userId)
// Database, Logger, EmailSender is the visibility module
Database db = new Database ();
Logger log = new Logger ();
log.LogInfo ("Order has been checkout");
EmailSender es = new EmailSender ();
Code after the redesign, apply a DIP:
In practice, people often apply the Dependency Injection pattern to ensure the DIP principle in the code.
DIP is used the most in code, but it is also controversial. Besides some advantages, DIP also comes with some disadvantages:
- Reduced cohesion between modules
- The code is easy to maintain, easy to replace the module.
- It’s easy to test and write a Unit Test.
- The concept of DI is quite “indigestible”; new developers will have difficulty learning.
- Using the interface can sometimes be difficult to debug, as it is not known exactly which module is called.
- Increased code complexity
What is object-oriented design? What is it all about? What are its benefits? What is it costs? It may seem silly to…
Dependency Injection Is NOT The Same As The Dependency Inversion Principle
A long time ago, when I first started blogging with LosTechies, I wrote up a few posts on Dependency Inversion and…
A curry of Dependency Inversion Principle (DIP), Inversion of Control (IoC), Dependency Injection…
Welcome to my post. Here I will try to describe DIP, IoC, DI, and IoC container. Most of the time, beginner developer…