设计模式六大原则之一的依赖倒置原则(

ops/2024/9/25 15:26:47/

设计模式六大原则之一的依赖倒置原则(Dependency Inversion Principle, DIP)是面向对象设计中的重要指导原则,它强调了软件设计中类与类之间的依赖关系应当如何合理构建,以提高系统的灵活性、可维护性和可扩展性。以下是对依赖倒置原则的详细阐述,包括其定义、核心思想、实现方式、优点、缺点以及应用实例。

一、定义

依赖倒置原则由罗伯特·马丁(Robert C. Martin)提出,其核心理念是“高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象”。这里的“高层模块”和“低层模块”是相对的,指的是在软件架构中处于不同层次的组件或模块。该原则要求我们在设计时,应当尽量依赖于抽象接口或抽象类,而不是具体的实现类,从而降低模块之间的耦合度。

二、核心思想

依赖倒置原则的核心思想可以归纳为以下几点:

  1. 高层模块不依赖低层模块:在传统的软件开发中,高层模块(如业务逻辑层)往往直接依赖于低层模块(如数据访问层)。然而,这种做法使得高层模块与低层模块之间紧密耦合,一旦低层模块发生变化,高层模块也需要相应地进行修改。依赖倒置原则要求高层模块与低层模块之间通过抽象层(如接口或抽象类)进行交互,从而降低它们之间的直接依赖。

  2. 抽象不依赖细节:抽象层(如接口或抽象类)定义了模块之间的交互规则,但不依赖于具体的实现细节。这意味着抽象层的设计应当独立于具体的实现,以便于后续的替换和维护。

  3. 细节依赖抽象:具体的实现类(即细节)应当实现抽象层定义的接口或继承抽象类,从而确保它们的行为符合抽象层的规范。这样,当需要更换具体的实现时,只要新的实现类符合抽象层的规范,就可以无缝地替换旧的实现类,而不需要修改高层模块的代码。

三、实现方式

依赖倒置原则的实现方式主要包括以下几点:

  1. 使用接口或抽象类:通过定义接口或抽象类来规定模块之间的交互规则,使得高层模块与低层模块之间的依赖关系变得抽象化。

  2. 依赖注入:依赖注入是一种常见的实现依赖倒置原则的技术。它允许在运行时动态地将依赖关系注入到对象中,而不是在编译时静态地确定。这样,对象的依赖关系可以在运行时灵活地进行调整,从而提高了系统的灵活性和可扩展性。

  3. 遵循里氏替换原则:里氏替换原则是依赖倒置原则的一个补充,它要求子类能够替换父类而不影响程序的正确性。这意味着子类在继承父类时,必须遵守父类的行为契约,以确保替换后的系统仍然能够正常工作。

四、优点

依赖倒置原则具有以下几个显著的优点:

  1. 降低耦合度:通过依赖于抽象接口而不是具体实现,依赖倒置原则降低了模块之间的耦合度,使得系统更加灵活和可维护。

  2. 提高可扩展性:当需要添加新的功能或修改现有功能时,只需要在抽象层进行扩展或修改,而不需要修改高层模块的代码。这使得系统更加容易进行扩展和维护。

  3. 提高可重用性:抽象层定义了模块之间的交互规则,而具体的实现类则负责实现这些规则。由于抽象层与具体的实现类之间是相互独立的,因此抽象层可以被多个系统或模块重用。

  4. 支持单元测试:由于高层模块依赖于抽象接口而不是具体实现,因此可以轻松地编写针对高层模块的单元测试。这些单元测试不需要依赖于具体的实现类,从而提高了测试的独立性和可靠性。

五、缺点

尽管依赖倒置原则具有许多优点,但它也存在一些缺点:

  1. 增加系统的复杂性:由于需要定义大量的接口和抽象类来规定模块之间的交互规则,因此可能会增加系统的复杂性。这要求开发者需要具备更高的抽象思维能力和设计能力来应对这种复杂性。

  2. 可能导致过度设计:在某些情况下,开发者可能会过度关注抽象和接口的设计而忽略了实际的业务需求。这可能会导致设计出过于复杂或不必要的接口和抽象类从而增加了系统的负担。

  3. 增加开发和维护成本:由于需要编写更多的接口和抽象类以及进行依赖注入等操作,因此可能会增加开发和维护的成本。这要求开发者需要投入更多的时间和精力来确保系统的正确性和稳定性。

六、应用实例

依赖倒置原则在软件开发中有着广泛的应用实例。以下是一个简单的例子来说明如何应用依赖倒置原则

假设我们正在开发一个在线购物系统,其中包括购物车(ShoppingCart)和支付服务(PaymentService)两个模块。在传统的设计中,购物车模块可能会直接依赖于具体的支付服务实现类(如CreditCardPaymentService)。然而,这种做法会导致购物车模块与支付服务模块之间紧密耦合。如果我们需要添加新的支付服务(如PayPalPayment


http://www.ppmy.cn/ops/97943.html

相关文章

linux内存相关

Linux内核内存申请的方式有哪些? 内核申请内存的接口,如下介绍。 kmalloc 该函数一般是用于内核申请小于page size的内存,分配的内存是物理连续的,至于kmalloc的具体实现,需要参考内核内存分配器配置的是slab、slob…

微服务的保护

一、雪崩问题及解决方案 1.雪崩问题 微服务之间,一个微服务依赖多个其他的微服务。当一个微服务A依赖的一个微服务B出错时,微服务A会被阻塞,但其他不依赖于B的微服务不会受影响。 当有多个微服务依赖于B时,服务器支持的线程和并…

Android 上下滑隐藏显示状态栏

一、DisplayPolicy类中监听滑动事件,然后发送广播事件 Android12类路径: frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.javamSystemGestures new SystemGesturesPointerEventListener(mUiContext, mHandler,new SystemGest…

修改TMS IWAdvWebGrid日期格式

一。 修改两个res文件 tmsiwcal.res 和 tmsiwgridcal.RES 将stgl(sel)函数(选择值放入编辑框)中的这部分修改,设置格式 YYYY-MM-DD ,这是选择日期返回值的格式,res文件大小不能变. (应该有办法转换res文件,取出修改后写回&…

Android app安装第三方应用

在Android设备上安装第三方应用通常涉及一系列步骤,这些步骤可能会因Android版本的不同而有所差异。但大致流程可以归纳为以下几个关键步骤: 1、开启权限 开启“允许安装未知来源应用”,可以去安全设置那里设置允许安装未知来源,…

无人机飞手培训:考证、组装、维修技术详解

随着无人机技术的飞速发展,无人机已广泛应用于航拍、农业、环境监测、救援等多个领域,成为现代社会不可或缺的工具之一。作为无人机操作的核心——无人机飞手,其专业技能的掌握至关重要。本文档将详细解析无人机飞手培训的关键环节&#xff0…

阿里MAXCOMPUTE数据专辑信息读取并同步数据表

阿里MAXCOMPUTE数据专辑信息读取并同步数据表 在阿里云大数据体系中,我们可以使用数据地图的数据专辑,对数据的类别等进行一个管理 那么管理后的数据,我们想要落表进行相关的数据分析,如何做呢? 查看阿里云官方文档…

优雅处理枚举前端丢失大Long精度问题

1. 枚举-json处理&#xff08;前端 <> 后端 <> 数据库&#xff09; 前端传递 枚举code 后端响应 枚举code 表里存储 枚举code 内存处理 枚举对象 Getter AllArgsConstructor JsonFormat(shape JsonFormat.Shape.OBJECT) public enum SexEnum {MALE(0, "男&…