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

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

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

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

SE(Secure Element)加密芯片与MCU协同工作的典型流程

以下是SE&#xff08;Secure Element&#xff09;加密芯片与MCU协同工作的典型流程&#xff0c;综合安全认证、数据保护及防篡改机制&#xff1a; 一、基础认证流程&#xff08;参数保护方案&#xff09; 密钥预置‌ SE芯片与MCU分别预置相同的3DES密钥&#xff08;Key1、Key2…...

git删除本地分支和远程分支

删除本地分支 git branch -d 分支名删除远程分支 git push origin --delete 分支名...

SQL 注入开放与修复

开发&#xff1a; SQL 注入是一种数据库攻击手段。攻击者通过向应用程序提交恶意代码来改变原 SQL 语句的含义&#xff0c; 进而执行任意 SQL 命令&#xff0c;达到入侵数据库乃至操作系统的目的。 例如&#xff1a;下面代码片段中&#xff0c;动态构造并执行了一个 SQ…...