设计模式六大原则之:依赖倒置原则
1. 依赖倒置原则简介
依赖倒置原则(Dependency Inversion Principle, DIP) 是面向对象设计的核心原则之一,由罗伯特·马丁(Robert C. Martin)提出,旨在降低类间的依赖度,使之更易于维护和扩展。该原则主张高层模块不应该依赖于底层模块,两者都应依赖于抽象接口。
依赖倒置原则强调的是通过引入接口和抽象类来代替直接的类依赖,使得系统设计更灵活,组件间的耦合度更低。这有助于提升系统的整体复用性和扩展性。
它要求程序在设计和实现时应该依赖于抽象接口,而不是直接依赖于具体的实现。依赖倒置原则的实现关键在于对抽象进行编程,而非对实现进行编程,从而使得软件设计更加灵活和可扩展。
2. 依赖倒置原则核心思想

依赖倒置原则包含以下三层含义:
-
高层模块不应该依赖低层模块:这里的“高层”和“低层”指的是模块之间的依赖关系。按照依赖倒置原则,无论是高层模块还是低层模块,都应该依赖于抽象,而不是直接依赖于具体的实现。这样,当底层模块发生变化时,高层模块不需要进行修改,从而提高了系统的可维护性和可扩展性。
-
抽象不应该依赖细节:抽象层(如接口或抽象类)定义了模块之间的交互规则,而不应该依赖于具体的实现细节。这意味着抽象层的设计应该独立于具体的实现,以便于后续的替换和维护。
-
细节应该依赖抽象:具体的实现类(细节)应该实现抽象层定义的接口或继承抽象类,从而确保它们的行为符合抽象层的规范。这样,当需要更换具体的实现时,只要新的实现类符合抽象层的规范,就可以无缝地替换旧的实现类,而不需要修改高层模块的代码。
依赖倒置原则强调通过依赖于抽象接口而不是具体实现,可以减少代码之间的直接依赖,使得代码更加模块化、可重用,并且更容易进行单元测试和维护。此外,这一原则也是面向对象设计中的一个重要概念,它强调了抽象化的重要性,并通过抽象化来降低代码之间的耦合度,提高软件的质量和可维护性。
3. 依赖倒置原则应用场景
- 设计模式:例如工厂模式、策略模式等,都是依赖倒置原则的应用实例。
- 分层架构:在MVC(模型-视图-控制器)或分层软件体系结构中,每一层依赖于上一层提供的接口或抽象类。
- 微服务架构:服务间通过接口通信,而非直接互相依赖。
4. 依赖倒置原则优点

依赖倒置原则(Dependency Inversion Principle, DIP)有以下几个显著的优点:
-
高内聚,低耦合:通过依赖于抽象接口或抽象类,降低了组件之间的相互依赖,使得修改或替换底层实现变得更容易,减少了“牵一发而动全身”的风险,提高了代码的独立性和稳定性。
-
灵活性:由于高层模块与具体实现解耦,可以方便地添加、删除或替换底层实现,适应不断变化的需求。例如,在测试环境中,可以用模拟实现替代生产环境中的复杂服务。
-
模块化与扩展性:每个模块只关心它应该做什么,而不关心是谁在做这件事,这有利于模块的独立开发和维护。新功能的添加通常只需要增加一个新的实现,而不必改动已有的高层模块。
-
提高可测试性:因为高层模块不直接依赖于具体实现,它们更容易单元测试。我们可以对每个模块编写单独的测试用例,而不需要担心其他部分的影响。
-
减少代码冗余:当需要修改基础逻辑时,只需在一个地方更改接口,所有依赖这个接口的地方都能自动受益,避免了代码复制和粘贴导致的问题。
-
符合开闭原则:DIP是开闭原则的具体体现,即对扩展开放,对修改关闭。这意味着增加新的功能时,只需要添加新的实现,而不是修改现有的代码。
5. 依赖倒置原则使用步骤
- 定义接口或抽象类:首先,确定业务中共享的行为并创建相应的接口或抽象类。
- 抽象高层模块:让高层模块依赖这些接口,而非具体的实现。
- 实现接口:创建具体的类并实现这些接口。
- 调用者注入依赖:在使用这些高层模块的地方,传入相应的实现对象,而非硬编码。
6. 依赖倒置原则代码示例
// 模型:抽象接口
interface PaymentService {void processPayment();
}// 具体实现:依赖倒置
class CreditCardPaymentService implements PaymentService {@Overridepublic void processPayment() { /* ... */ }
}// 控制器:高层模块,依赖抽象
class ShoppingCartController {private PaymentService paymentService;public ShoppingCartController(PaymentService service) {this.paymentService = service;}public void checkout() {paymentService.processPayment();}
}// 测试时更换支付服务
public class Test {public static void main(String[] args) {ShoppingCartController controller = new ShoppingCartController(new CreditCardPaymentService());// 或者在运行时切换为另一种支付服务controller.paymentService = new PayPalPaymentService();controller.checkout();}
}
7. 总结
综上,依赖倒置原则(Dependency Inversion Principle, DIP)是面向对象设计中的一个基本原则,它提倡高层模块不应该依赖于低层模块,而是两者都应该依赖于抽象。简单来说,就是“针对接口编程,而不是针对实现”。
这个原则鼓励我们编写可测试、灵活和易于维护的代码,通过接口或抽象类来规定系统组件之间的交互,使得当底层实现改变时,高层模块不需要做修改,只需要关注接口的变化即可。这有助于降低系统的耦合度,提高整体架构的稳定性。
相关文章:
设计模式六大原则之:依赖倒置原则
1. 依赖倒置原则简介 依赖倒置原则(Dependency Inversion Principle, DIP) 是面向对象设计的核心原则之一,由罗伯特马丁(Robert C. Martin)提出,旨在降低类间的依赖度,使之更易于维护和扩展。该原则主张高层模块不应该依赖于底层模块&#x…...
06_Linux中如何让程序重启后自动启动
Linux中如何让程序重启后自动启动 systemd单元文件1.创建服务文件!!!服务配置文件的介绍 2.需要配置服务的状态(加载和启用服务)3.验证服务程序的运行状态4.打印程序的标准输出 systemd单元文件 Systemd 是现代 Linux…...
优化业务流程的关键:深入探讨BPA流程设计
在当前竞争激烈的商业环境中,业务流程自动化(BPA)已经成为企业提升效率、减少成本和提高业务灵活性的关键工具。今天,我们将深入探讨BPA流程设计的重要性及其实施步骤,为企业提供实用的指南。 什么是BPA? …...
qt工程中调用sdl的流程
配置 Qt 工程 在你的 Qt 工程中,需要对项目文件(.pro 文件)进行配置,以包含 SDL 库的路径和链接选项。 # Qt Project File (.pro)# 设置 SDL 库的路径 INCLUDEPATH /path/to/SDL/include LIBS -L/path/to/SDL/lib -lSDL2初始化…...
ECMAScript性能优化技巧与陷阱
大家好,我是程序员小羊! 前言 ECMAScript,即JavaScript,是一种广泛应用于Web开发中的脚本语言。随着现代Web应用的复杂度日益增加,如何优化JavaScript的性能变得至关重要。性能优化不仅能提高应用的响应速度&#x…...
c++实现B树(上)
哈喽啊!好久不见,甚是想念!失踪人口要回归了,时隔一个多月小吉我终于要更新blog了🎉。在停更的一个多月中,小吉也有在好好学习提升自己,立志给大家呈现好文章。 现在让我们进入正题吧…...
【机器学习】深度强化学习–RL的基本概念、经典场景以及算法分类
引言 深度强化学习(Deep Reinforcement Learning, DRL)是机器学习的一个分支,它结合了深度学习(Deep Learning)和强化学习(Reinforcement Learning, RL)的技术 文章目录 引言一、深度强化学习–…...
【git】将本地文件上传到github
安装git 选择一个文件夹作为git仓库,cd到文件夹输入 git init文件夹出现.git文件夹,该文件夹默认为隐藏文件夹,设置为不隐藏 在cmd中输入 ssh-keygen -t rsa -C "xxxxxx.com"该邮箱为github邮箱,然后一路enter出现以…...
安卓应用开发学习:手机摇一摇功能应用尝试--摇骰子和摇红包
一、引言 前几天,我发布的日志《安卓应用开发学习:查看手机传感器信息》记录了如何查看手机传感器的信息,通过上述的方法,可以看到我的OPPO手机支持19种传感器。本篇日志就记录一下常见的加速度传感器的典型应用——“摇一摇”功…...
HTML中的<fieldset>标签元素框的使用
HTML 提供的 <fieldset> 标签用于在表单中分组相关元素。 <fieldset> 标签会在相关元素周围绘制一个框。 <legend> 标签为 fieldset 元素定义标题。 语法如下: <fieldset><legend>标题</legend><!-- 元素内容... -->…...
Linux驱动入门实验班——SR501红外模块驱动(附百问网视频链接)
目录 一、工作方式 二、接口图 三、编写思路 1.构造file_operations结构体 2.实现read函数 3.编写入口函数 4.编写中断处理函数 5.编写出口函数 6.声明出入口函数以及协议 四、源码 五、课程链接 一、工作方式 SR501人体红外感应模块有两种工作模式: …...
windows C++- Com技术简介(上)
在介绍C和winrt与COM组件技术的关系之前,有必要介绍一下com组件技术,这项技术比较古老,但是它一直作为windows的基石存在。COM 是一类独立于平台且面向对象的分布式系统,用于创建可交互的二进制软件组件。 COM 技术是 Microsoft O…...
Jenkins持续集成工具学习
一、从装修厨房看项目开发效率优化 二、持续集成工具 三、JavaEE项目部署方式对比 四、JenkinsSVN持续集成环境搭建 五、JenkinsGitHub持续集成环境搭建...
Redis:查询是否包含某个字符/字符串之三
上一篇:Redis:查询是否包含某个字符/字符串之二-CSDN博客 摘要: 遍历key,在跟进value的类型遍历value是否包含指定字符串 search_strings ,这里使用redis-py库,默认只能处理utf-8编码,如果存在…...
【Redis】数据类型详解及其应用场景
目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维⾮常重要,同时掌握每种数据结构的常⻅…...
PARA-Drive:设计并行模型实现端到端自动驾驶
论文链接 https://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_for_Real-time_Autonomous_Driving_CVPR_2024_paper.pdfhttps://openaccess.thecvf.com/content/CVPR2024/papers/Weng_PARA-Drive_Parallelized_Architecture_fo…...
vs2022 x64 C/C++和汇编混编 遇到的坑
vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用?结论 遇到的问题 0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole…...
PHP概述、环境搭建与基本语法讲解
目录 【学习目标、重难点知识】 什么是网站? 1. PHP 介绍 1.1. PHP 概述 1.1.1. PHP 是什么? 1.1.2. PHP 都能做什么? 1.2. PHP 环境搭建 1.2.1. PhpStudy 2. PHP 基本语法 2.1. PHP 语法入门 2.1.1. 第一个 PHP 程序 2.1.2. PHP …...
实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)
随着信创国产化浪潮的来临,在国产操作系统上的应用开发的需求越来越多,其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音,将它们录制成一个mp4文件。那么这个要如何实现了? 一. 技术方案 要完成这些功能&a…...
深度学习9--目标检测
1.概念介绍 目标检测不仅可以检测数字,而且可以检测动物的种类、汽车的种类等。例如,自动驾驶车辆需要自动识别前方物体是车辆还是行人,需要自动识别道路两 旁的指示牌和前方的红绿灯颜色。对于自动检测的算法,有两个要求…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...

