当前位置: 首页 > news >正文

设计模式六大原则之:依赖倒置原则

1. 依赖倒置原则简介

依赖倒置原则(Dependency Inversion Principle, DIP) 是面向对象设计的核心原则之一,由罗伯特·马丁(Robert C. Martin)提出,旨在降低类间的依赖度,使之更易于维护和扩展。该原则主张高层模块不应该依赖于底层模块,两者都应依赖于抽象接口。

依赖倒置原则强调的是通过引入接口和抽象类来代替直接的类依赖,使得系统设计更灵活,组件间的耦合度更低。这有助于提升系统的整体复用性和扩展性

它要求程序在设计和实现时应该依赖于抽象接口,‌而不是直接依赖于具体的实现。‌依赖倒置原则的实现关键在于抽象进行编程,‌而非对实现进行编程,‌从而使得软件设计更加灵活和可扩展。‌

2. 依赖倒置原则核心思想

依赖倒置原则包含以下三层含义:‌

  1. 高层模块不应该依赖低层模块:‌这里的“高层”和“低层”指的是模块之间的依赖关系。‌按照依赖倒置原则,‌无论是高层模块还是低层模块,‌都应该依赖于抽象,‌而不是直接依赖于具体的实现。‌这样,‌当底层模块发生变化时,‌高层模块不需要进行修改,‌从而提高了系统的可维护性和可扩展性。‌

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

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

依赖倒置原则强调通过依赖于抽象接口而不是具体实现,‌可以减少代码之间的直接依赖,‌使得代码更加模块化、‌可重用,‌并且更容易进行单元测试和维护。‌此外,‌这一原则也是面向对象设计中的一个重要概念,‌它强调了抽象化的重要性,‌并通过抽象化来降低代码之间的耦合度,‌提高软件的质量和可维护性。‌

3. 依赖倒置原则应用场景

  1. 设计模式:例如工厂模式、策略模式等,都是依赖倒置原则的应用实例。
  2. 分层架构:在MVC(模型-视图-控制器)或分层软件体系结构中,每一层依赖于上一层提供的接口或抽象类。
  3. 微服务架构:服务间通过接口通信,而非直接互相依赖。

4. 依赖倒置原则优点

依赖倒置原则(Dependency Inversion Principle, DIP)有以下几个显著的优点:

  1. 高内聚,低耦合:通过依赖于抽象接口或抽象类,降低了组件之间的相互依赖,使得修改或替换底层实现变得更容易,减少了“牵一发而动全身”的风险,提高了代码的独立性和稳定性。

  2. 灵活性:由于高层模块与具体实现解耦,可以方便地添加、删除或替换底层实现,适应不断变化的需求。例如,在测试环境中,可以用模拟实现替代生产环境中的复杂服务。

  3. 模块化与扩展性:每个模块只关心它应该做什么,而不关心是谁在做这件事,这有利于模块的独立开发和维护。新功能的添加通常只需要增加一个新的实现,而不必改动已有的高层模块。

  4. 提高可测试性:因为高层模块不直接依赖于具体实现,它们更容易单元测试。我们可以对每个模块编写单独的测试用例,而不需要担心其他部分的影响。

  5. 减少代码冗余:当需要修改基础逻辑时,只需在一个地方更改接口,所有依赖这个接口的地方都能自动受益,避免了代码复制和粘贴导致的问题。

  6. 符合开闭原则:DIP是开闭原则的具体体现,即对扩展开放,对修改关闭。这意味着增加新的功能时,只需要添加新的实现,而不是修改现有的代码。

5. 依赖倒置原则使用步骤

  1. 定义接口或抽象类:首先,确定业务中共享的行为并创建相应的接口或抽象类。
  2. 抽象高层模块:让高层模块依赖这些接口,而非具体的实现。
  3. 实现接口:创建具体的类并实现这些接口。
  4. 调用者注入依赖:在使用这些高层模块的地方,传入相应的实现对象,而非硬编码。

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了🎉。在停更的一个多月中,小吉也有在好好学习提升自己,立志给大家呈现好文章。  现在让我们进入正题吧&#xf…...

【机器学习】深度强化学习–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 元素定义标题。 语法如下&#xff1a; <fieldset><legend>标题</legend><!-- 元素内容... -->…...

Linux驱动入门实验班——SR501红外模块驱动(附百问网视频链接)

目录 一、工作方式 二、接口图 三、编写思路 1.构造file_operations结构体 2.实现read函数 3.编写入口函数 4.编写中断处理函数 5.编写出口函数 6.声明出入口函数以及协议 四、源码 五、课程链接 一、工作方式 SR501人体红外感应模块有两种工作模式&#xff1a; …...

windows C++- Com技术简介(上)

在介绍C和winrt与COM组件技术的关系之前&#xff0c;有必要介绍一下com组件技术&#xff0c;这项技术比较古老&#xff0c;但是它一直作为windows的基石存在。COM 是一类独立于平台且面向对象的分布式系统&#xff0c;用于创建可交互的二进制软件组件。 COM 技术是 Microsoft O…...

Jenkins持续集成工具学习

一、从装修厨房看项目开发效率优化 二、持续集成工具 三、JavaEE项目部署方式对比 四、JenkinsSVN持续集成环境搭建 五、JenkinsGitHub持续集成环境搭建...

Redis:查询是否包含某个字符/字符串之三

上一篇&#xff1a;Redis&#xff1a;查询是否包含某个字符/字符串之二-CSDN博客 摘要&#xff1a; 遍历key&#xff0c;在跟进value的类型遍历value是否包含指定字符串 search_strings &#xff0c;这里使用redis-py库&#xff0c;默认只能处理utf-8编码&#xff0c;如果存在…...

【Redis】数据类型详解及其应用场景

目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构&#xff0c;理解每种数据结构的特点对于 Redis 开发运维⾮常重要&#xff0c;同时掌握每种数据结构的常⻅…...

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 对奇数个寄存器有用&#xff1f;结论 遇到的问题 0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole…...

PHP概述、环境搭建与基本语法讲解

目录 【学习目标、重难点知识】 什么是网站&#xff1f; 1. PHP 介绍 1.1. PHP 概述 1.1.1. PHP 是什么&#xff1f; 1.1.2. PHP 都能做什么&#xff1f; 1.2. PHP 环境搭建 1.2.1. PhpStudy 2. PHP 基本语法 2.1. PHP 语法入门 2.1.1. 第一个 PHP 程序 2.1.2. PHP …...

实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)

随着信创国产化浪潮的来临&#xff0c;在国产操作系统上的应用开发的需求越来越多&#xff0c;其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音&#xff0c;将它们录制成一个mp4文件。那么这个要如何实现了&#xff1f; 一. 技术方案 要完成这些功能&a…...

深度学习9--目标检测

1.概念介绍 目标检测不仅可以检测数字&#xff0c;而且可以检测动物的种类、汽车的种类等。例如&#xff0c;自动驾驶车辆需要自动识别前方物体是车辆还是行人&#xff0c;需要自动识别道路两 旁的指示牌和前方的红绿灯颜色。对于自动检测的算法&#xff0c;有两个要求&#xf…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!

多连接 BLE 怎么设计服务不会乱&#xff1f;分层思维来救场&#xff01; 作者按&#xff1a; 你是不是也遇到过 BLE 多连接时&#xff0c;调试现场像网吧“掉线风暴”&#xff1f; 温度传感器连上了&#xff0c;心率带丢了&#xff1b;一边 OTA 更新&#xff0c;一边通知卡壳。…...

Ray框架:分布式AI训练与调参实践

Ray框架&#xff1a;分布式AI训练与调参实践 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 Ray框架&#xff1a;分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...