什么是依赖倒置原则

简介: 依赖倒置原则(Dependency Inversion Principle, DIP)是面向对象设计中的SOLID原则之一,强调高层模块不应依赖低层模块,双方应依赖于抽象。该原则包含两方面:抽象不依赖细节,细节依赖抽象。这有助于降低耦合度、提高模块化和灵活性。实践中可通过接口定义契约、依赖注入等方式实现。例如,在Java中定义`MessageService`接口及其实现`EmailService`,高层`NotificationService`依赖于`MessageService`接口而非具体实现,从而实现了对扩展开放、对修改关闭的设计目标。

依赖倒置原则(Dependency Inversion Principle, DIP)是面向对象设计原则之一,它是SOLID原则中的"D"。依赖倒置原则的核心思想是高层策略性业务规则不应该依赖于低层的具体实现细节,而两者都应该依赖于抽象。

依赖倒置原则主要包含两个基本点:

  1. 抽象不应该依赖于细节:系统中的抽象层(高层模块)不应当依赖于具体实现(低层模块),而是两者都应该依赖于抽象(如接口或抽象类)。

  2. 细节应该依赖于抽象:具体的实现应该依赖于抽象,这样在不修改抽象层代码的情况下,可以替换或修改具体的实现。

依赖倒置原则的优点包括:

  • 降低耦合度:由于模块间的依赖是基于抽象的,因此减少了模块间的直接依赖,降低了耦合度。
  • 提高模块化:系统更容易被分解为可复用的模块,因为模块间的交互是通过抽象接口进行的。
  • 增强灵活性:更换或升级系统的某个部分变得更加容易,因为具体实现可以独立于高层策略进行变化。

在实际应用中,依赖倒置原则可以通过以下方式实现:

  • 使用接口或抽象类定义系统组件之间的契约。
  • 通过依赖注入(Dependency Injection, DI)将具体实现注入到需要它们的对象中,而不是让对象自己创建或查找这些实现。
  • 避免在高层模块中直接使用具体类,而是通过抽象来引用。

依赖倒置原则是实现开闭原则(Open/Closed Principle)的基础,即软件实体应该对扩展开放,对修改关闭。通过依赖倒置,我们可以更容易地扩展系统功能,而不需要修改现有的代码。

下面来看一个简单的Java代码示例,让我们更好的理解依赖倒置原则的应用:

首先,我们定义一个抽象接口,表示一个可以发送消息的系统:

public interface MessageService {
   
    void sendMessage(String message);
}

然后,我们创建一个具体的发送服务实现这个接口:

public class EmailService implements MessageService {
   
    @Override
    public void sendMessage(String message) {
   
        System.out.println("Sending email: " + message);
    }
}

接下来,我们有一个高层策略类,它使用MessageService接口而不是具体的EmailService类:

public class NotificationService {
   
    private MessageService messageService;

    // 构造函数注入依赖
    public NotificationService(MessageService messageService) {
   
        this.messageService = messageService;
    }

    public void notifyUser(String message) {
   
        // 依赖于抽象,而不是具体实现
        messageService.sendMessage(message);
    }
}

最后,我们可以在客户端代码中使用这个系统:

public class Client {
   
    public static void main(String[] args) {
   
        // 创建具体的消息服务
        MessageService emailService = new EmailService();

        // 将具体的消息服务注入到高层策略中
        NotificationService notificationService = new NotificationService(emailService);

        // 使用高层策略发送消息
        notificationService.notifyUser("Hello, this is a test email.");
    }
}

在这个例子中,NotificationService类是一个高层策略类,它依赖于MessageService接口的抽象。我们通过构造函数注入具体的消息服务EmailService。这样,如果将来我们需要更换消息服务的实现(比如使用SmsService),我们只需要创建一个新的实现类并注入到NotificationService中,而不需要修改NotificationService的代码。这就体现了依赖倒置原则的精神。

相关实践学习
通过轻量消息队列(原MNS)主题HTTP订阅+ARMS实现自定义数据多渠道告警
本场景将自定义告警信息同时分发至多个通知渠道的需求,例如短信、电子邮件及钉钉群组等。通过采用轻量消息队列(原 MNS)的主题模型的HTTP订阅方式,并结合应用实时监控服务提供的自定义集成能力,使得您能够以简便的配置方式实现上述多渠道同步通知的功能。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
6月前
|
设计模式 Java 数据库
06.依赖倒置原则介绍
依赖倒置原则是面向对象设计六大原则之一,强调高层模块不应依赖低层模块,两者应依赖于抽象。通过依赖接口或抽象类而非具体实现,降低模块耦合度,提升系统灵活性和可维护性。本文详解该原则的概念、目标、思想及其实现方式(如依赖注入),并结合多数据库操作、用户购买家电、发送消息等实际案例,深入探讨其应用与优缺点。
445 4
|
SQL XML 安全
mybatis批量更新数据三种方法效率对比【Mysql】
mybatis批量更新数据三种方法效率对比【Mysql】
4653 0
mybatis批量更新数据三种方法效率对比【Mysql】
|
9月前
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
355 13
Junit4中的新断言assertThat的使用方法
Junit4中的新断言assertThat的使用方法
366 0
|
存储 数据库 数据格式
深入理解依赖倒置原则(Dependence Inversion Principle)
深入理解依赖倒置原则(Dependence Inversion Principle)
1034 0
|
10月前
|
XML 前端开发 Android开发
Kotlin教程笔记(80) - MVVM架构设计
Kotlin教程笔记(80) - MVVM架构设计
|
9月前
|
设计模式 Java C#
装饰模式(Decorator Pattern)
装饰模式是一种结构型设计模式,允许在不修改原有对象的情况下动态添加功能。它通过装饰类层层叠加实现功能扩展,适用于需要在运行时动态添加、修改或移除对象行为的场景。装饰模式的核心角色包括抽象组件、具体组件、抽象装饰和具体装饰。该模式的优点在于动态扩展功能、避免类爆炸和遵守开放-封闭原则,但可能会导致对象数量增加和调试困难。常见使用场景包括图形系统中的动态效果和输入流的功能扩展。
240 0
|
Java 编译器
成功解决:java file outside of source root
解决Java文件不在源代码根目录内的问题,可以通过在IDEA中将包含.java文件的目录设置为Sources Root来修复。
成功解决:java file outside of source root
|
存储 消息中间件 JSON
DDD基础教程:一文带你读懂DDD分层架构
DDD基础教程:一文带你读懂DDD分层架构
|
消息中间件 存储 监控
消息队列在分布式系统中如何保证数据的一致性和顺序?
消息队列在分布式系统中如何保证数据的一致性和顺序?

热门文章

最新文章