Small Talk on Design Patterns (6)—Dependency Inversion Principle

Column introduction

Column address

link

Column introduction

It mainly analyzes and summarizes the 23 common design patterns currently on the market one by one. I hope that interested friends can take a look and it will be continuously updated. I hope you can supervise me and we can learn and make progress together. Come on, everyone.
Insert image description here

dependency inversion principle

The Dependency Inversion Principle (DIP) is an important principle in object-oriented design, which guides how to build loosely coupled, scalable and maintainable software systems. This principle was proposed by Robert C. Martin.

main idea

Decouple dependencies between high-level modules and low-level modules through abstraction.
Insert image description here

Key point analysis

a

High-level modules should not rely on the specific implementation of low-level modules, but on abstract interfaces. This means that high-level modules should define an abstract interface and low-level modules implement this interface. By relying on abstract interfaces, high-level modules can be programmed independently of concrete implementations.

b

Abstract interfaces should be defined by high-level modules, not by low-level modules. This ensures that high-level modules have control over dependencies without being restricted by low-level modules. High-level modules can define interface methods and properties according to their own needs without relying on the specific implementation details of low-level modules.

c

Dependency injection is an important means to implement the dependency inversion principle. Through dependency injection, high-level modules can pass objects of concrete implementation classes to abstract interfaces. Dependency injection can be achieved through constructor, method parameter or property injection. This can achieve decoupling, and high-level modules do not need to care about the creation and management of specific implementation classes.
Insert image description here

Advantages and Disadvantages Analysis

advantage

Reduce coupling between modules

Through the dependency inversion principle, high-level modules do not depend on the specific implementation of low-level modules, but on abstract interfaces. This can reduce the coupling between modules and improve the flexibility and maintainability of the code.

Improve code scalability

Since high-level modules do not depend on the specific implementation of low-level modules, when a low-level module needs to be added or modified, only the specific implementation class needs to be modified without modifying the code of the high-level module. This improves the scalability of the code and reduces the impact on existing code.

Facilitates unit testing

Since high-level modules rely on abstract interfaces, unit testing can be performed by using mock objects without relying on concrete implementation classes. This makes testing easier and improves the quality of your code.

Insert image description here

shortcoming

Increase code complexity

The principle of dependency inversion requires the introduction of mechanisms such as abstract interfaces and dependency injection, which will increase the complexity of the code and the difficulty of understanding it. Especially in smaller projects or simple scenarios, introducing these mechanisms may appear to be too cumbersome.

Requires additional design and development work

When applying the dependency inversion principle, additional design and development work is required, including defining abstract interfaces, implementing concrete implementation classes, and performing dependency injection. This increases development costs and effort.

To sum up, the dependency inversion principle can improve the flexibility, maintainability and scalability of the code to a certain extent, but it also needs to be weighed against the complexity and development costs it introduces. During the design and development process, it is necessary to decide whether to adopt the dependency inversion principle based on specific scenarios and requirements.

Java code implementation

// 定义抽象接口
public interface MessageSender {
    
    
    void sendMessage(String message);
}

// 具体实现类1
public class EmailSender implements MessageSender {
    
    
    @Override
    public void sendMessage(String message) {
    
    
        System.out.println("Sending email: " + message);
    }
}

// 具体实现类2
public class SmsSender implements MessageSender {
    
    
    @Override
    public void sendMessage(String message) {
    
    
        System.out.println("Sending SMS: " + message);
    }
}

// 高层模块,依赖于抽象接口
public class NotificationService {
    
    
    private MessageSender messageSender;

    // 通过构造函数进行依赖注入
    public NotificationService(MessageSender messageSender) {
    
    
        this.messageSender = messageSender;
    }

    public void sendNotification(String message) {
    
    
        // 调用抽象接口的方法
        messageSender.sendMessage(message);
    }
}

// 测试代码
public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 创建具体实现类的对象
        MessageSender emailSender = new EmailSender();
        MessageSender smsSender = new SmsSender();

        // 创建高层模块的对象,并传入具体实现类的对象
        NotificationService emailNotificationService = new NotificationService(emailSender);
        NotificationService smsNotificationService = new NotificationService(smsSender);

        // 调用高层模块的方法
        emailNotificationService.sendNotification("Hello, this is an email notification.");
        smsNotificationService.sendNotification("Hello, this is an SMS notification.");
    }
}

Insert image description here

Example analysis

The method of sending messages is defined in the abstract interface MessageSender. The specific implementation classes EmailSender and SmsSender respectively implement this interface and provide specific implementations of sending emails and sending text messages. The high-level module NotificationService relies on the abstract interface MessageSender and performs dependency injection through the constructor, thus realizing the dependency inversion principle.

Summarize

The principle of dependency inversion emphasizes the importance of abstract-oriented programming. Through technologies such as abstract interfaces and dependency injection, the coupling between modules can be reduced and the flexibility and maintainability of the code can be improved.

Guess you like

Origin blog.csdn.net/weixin_74888502/article/details/133436775