当前位置: 首页 > 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…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...