I. What is the dependency inversion principle?

Dependence Inversion Principle (DIP) refers to the Principle that when designing code structures, high-level modules should not rely on low-level modules, but both should rely on their abstractions. Abstraction should not depend on details; Details should depend on abstractions. Dependency inversion reduces class-to-class coupling, improves system stability, improves code readability and maintainability, and reduces the risk of modifying programs. Let’s take a look at an example, again using the course example, to create a class Mark:

2. Call:

3.Mark loves learning and is currently taking Java courses and Python courses. As we all know, learning can be addictive. With his interest in learning skyrocketing, Mark now wants to take AI courses as well. At this point, the business expands, and our code changes the code from bottom to top (the calling layer). Add a method of studyAICourse() to the Mark class and append it at the top level. As a result, after the system is released, it is actually very unstable, and it can bring unexpected risks when changing the code. Next, let’s tune our code to create an abstract ICourse interface for the course:

Then write the JavaCourse class:

To implement the PythonCourse class:

Modify the Mark class

Look at the call:

We will look at the code at this time. No matter how interested Mark is, for the new course, I just need to create a new class and tell Mark by passing the reference, without modifying the underlying code. This is actually a very familiar approach called dependency injection. There are also constructor and setter methods for injection. Let’s look at constructor injection:

Look at the calling code:

According to constructor injection, an instance is created each time it is called. So, if Mark is a global singleton, we have no choice but to use setters for injection and continue to modify the Mark class code:

Look at the calling code:

The complete code is as follows:

Mark class

DependenceInversionTest class


2. Complete class diagram

Now let’s look at the final class diagram: