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

小谈设计模式(6)—依赖倒转原则

小谈设计模式(6)—依赖倒转原则

  • 专栏介绍
    • 专栏地址
    • 专栏介绍
  • 依赖倒转原则
    • 核心思想
      • 关键点分析
        • a
        • b
        • c
    • 优缺点分析
      • 优点
        • 降低模块间的耦合度
        • 提高代码的可扩展性
        • 便于进行单元测试
      • 缺点
        • 增加代码的复杂性
        • 需要额外的设计和开发工作
    • Java代码实现
      • 示例分析
    • 总结

专栏介绍

专栏地址

link

专栏介绍

主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
在这里插入图片描述

依赖倒转原则

依赖倒转原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个重要原则,它指导着如何构建松耦合、可扩展和可维护的软件系统。该原则由罗伯特·C·马丁(Robert C. Martin)提出。

核心思想

通过抽象来解耦高层模块和低层模块之间的依赖关系。
在这里插入图片描述

关键点分析

a

高层模块不应该依赖于低层模块的具体实现,而是依赖于抽象接口。这意味着高层模块应该定义一个抽象接口,而低层模块实现该接口。通过依赖于抽象接口,高层模块可以独立于具体实现进行编程。

b

抽象接口应该由高层模块定义,而不是由低层模块定义。这样可以确保高层模块对于依赖的控制,而不会受到低层模块的限制。高层模块可以根据自己的需求定义接口的方法和属性,而不需要依赖于低层模块的具体实现细节。

c

依赖注入是实现依赖倒转原则的重要手段。通过依赖注入,高层模块可以将具体实现类的对象传递给抽象接口。依赖注入可以通过构造函数、方法参数或者属性注入的方式实现。这样可以实现解耦,高层模块不需要关心具体实现类的创建和管理。
在这里插入图片描述

优缺点分析

优点

降低模块间的耦合度

通过依赖倒转原则,高层模块不依赖于低层模块的具体实现,而是依赖于抽象接口。这样可以使得模块之间的耦合度降低,提高代码的灵活性和可维护性。

提高代码的可扩展性

由于高层模块不依赖于低层模块的具体实现,当需要新增或修改低层模块时,只需要修改具体实现类而不需要修改高层模块的代码。这样可以提高代码的可扩展性,减少对现有代码的影响。

便于进行单元测试

由于高层模块依赖于抽象接口,可以通过使用模拟对象来进行单元测试,而不需要依赖于具体实现类。这样可以更容易地进行测试,提高代码的质量。

在这里插入图片描述

缺点

增加代码的复杂性

依赖倒转原则需要引入抽象接口和依赖注入等机制,这会增加代码的复杂性和理解难度。特别是在项目规模较小或简单场景下,引入这些机制可能会显得过于繁琐。

需要额外的设计和开发工作

在应用依赖倒转原则时,需要进行额外的设计和开发工作,包括定义抽象接口、实现具体实现类、进行依赖注入等。这会增加开发成本和工作量。

综上所述,依赖倒转原则在一定程度上可以提高代码的灵活性、可维护性和可扩展性,但也需要权衡其引入的复杂性和开发成本。在设计和开发过程中,需要根据具体的场景和需求来决定是否采用依赖倒转原则。

Java代码实现

// 定义抽象接口
public interface MessageSender {void sendMessage(String message);
}// 具体实现类1
public class EmailSender implements MessageSender {@Overridepublic void sendMessage(String message) {System.out.println("Sending email: " + message);}
}// 具体实现类2
public class SmsSender implements MessageSender {@Overridepublic void sendMessage(String message) {System.out.println("Sending SMS: " + message);}
}// 高层模块,依赖于抽象接口
public class NotificationService {private MessageSender messageSender;// 通过构造函数进行依赖注入public NotificationService(MessageSender messageSender) {this.messageSender = messageSender;}public void sendNotification(String message) {// 调用抽象接口的方法messageSender.sendMessage(message);}
}// 测试代码
public class Main {public static void main(String[] args) {// 创建具体实现类的对象MessageSender emailSender = new EmailSender();MessageSender smsSender = new SmsSender();// 创建高层模块的对象,并传入具体实现类的对象NotificationService emailNotificationService = new NotificationService(emailSender);NotificationService smsNotificationService = new NotificationService(smsSender);// 调用高层模块的方法emailNotificationService.sendNotification("Hello, this is an email notification.");smsNotificationService.sendNotification("Hello, this is an SMS notification.");}
}

在这里插入图片描述

示例分析

在抽象接口MessageSender定义了发送消息的方法。具体实现类EmailSender和SmsSender分别实现了该接口,并提供了发送邮件和发送短信的具体实现。高层模块NotificationService依赖于抽象接口MessageSender,通过构造函数进行依赖注入,从而实现了依赖倒转原则。

总结

依赖倒置原则强调了面向抽象编程的重要性,通过抽象接口和依赖注入等技术,可以降低模块之间的耦合度,提高代码的灵活性和可维护性。

相关文章:

小谈设计模式(6)—依赖倒转原则

小谈设计模式(6)—依赖倒转原则 专栏介绍专栏地址专栏介绍 依赖倒转原则核心思想关键点分析abc 优缺点分析优点降低模块间的耦合度提高代码的可扩展性便于进行单元测试 缺点增加代码的复杂性需要额外的设计和开发工作 Java代码实现示例分析 总结 专栏介绍…...

JetBrains常用插件

Codota AI Autocomplete Java and JavaScript:自动补全插件 Background Image plus:背景图片设置 rainbow brackets:彩虹括号,便于识别 CodeGlance2: 类似于 Sublime 中的代码缩略图(代码小地图&#xff…...

【C++哈希应用】位图、布隆过滤器

【C哈希应用】位图、布隆过滤器 目录 【C哈希应用】位图、布隆过滤器位图概念位图的实现位图改造位图应用总结布隆过滤器布隆过滤器的提出布隆过滤器的概念布隆过滤器的查找布隆过滤器删除布隆过滤器优点布隆过滤器缺陷 作者:爱写代码的刚子 时间:2023.9…...

Qt 编译纯c的C99的项目, error: undefined reference to `f()‘

把Cpp的后缀该为C是什么样的 尝试引用一个奇门排盘的c程序,在git上找到的叫cqm, 然后总是报错 error: undefined reference to f() 很是郁闷 于是新建了个项目试验一下,终于摸清了需要命名空间。 后来这么写就可以了 a.h namespace XX …...

TensorFlow入门(五、指定GPU运算)

一般情况下,下载的TensorFlow版本如果是GPU版本,在运行过程中TensorFlow能自动检测。如果检测到GPU,TensorFlow会默认利用找到的第一个GPU来执行操作。如果机器上有超过一个可用的GPU,除第一个之外的其他GPU默认是不参与计算的。如果想让TensorFlow使用这些GPU执行操作,需要将运…...

Unity - 实践: Metallic流程贴图 转 Specular流程贴图

文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图,在 unity 中展示:M…...

第三章:最新版零基础学习 PYTHON 教程(第四节 - Python 运算符—Python 逻辑运算符及示例)

运算符用于对值和变量执行操作。这些是执行算术和逻辑计算的特殊符号。运算符运算的值称为操作数。 表中的内容逻辑运算符 逻辑与运算符 逻辑或运算符 逻辑非运算符 逻辑运算符的求值顺序 逻辑运算符 在 Python 中,逻辑运算符用于条件语句(True 或 False)。它们执行逻辑 AN…...

如何做好测试?(三)功能测试 (Functional Testing, FT)

1. 功能测试的详细介绍: 功能测试 (Functional Testing, FT),是一种软件测试方法,旨在验证系统的功能是否按照需求规格说明书或用户期望的方式正常工作。它关注系统的整体行为,以确保各个功能模块和组件之间的交互和集成正确。 …...

Ubuntu-Server-22.04安装桌面+VNC

前提:Ubuntu Server安装好后,ubantu其他版本是否适用这里未知,欢迎大佬们前来评论 一、默认没有图形界面,有时觉得用图形界面操作更简单直接,于是用如下命令安装: 1.更新本地环境 sudo apt-get update s…...

职业规划,什么是职业兴趣 - 我喜欢做什么?

能够在工作岗位上面做出成绩的人,都是结合自身兴趣,对职业进行合理规划的那一类。尤其是步入中年以后,能够创造出巨大价值的人,无一例外都是喜欢自己职业的人。没有将兴趣融入工作的人,只能够忍受默默无闻地活着&#…...

基于Java的高校学生党员发展流程管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

【NLP的python库(03/4) 】: 全面概述

一、说明 Python 对自然语言处理库有丰富的支持。从文本处理、标记化文本并确定其引理开始,到句法分析、解析文本并分配句法角色,再到语义处理,例如识别命名实体、情感分析和文档分类,一切都由至少一个库提供。那么,你…...

面试理论篇三

关于异常机制篇 异常描述 目录 关于异常机制篇异常描述 注:自用 1,Java中的异常分为哪几类?各自的特点是什么? Java中的异常 可以分为 可查异常(Checked Exception)、运行时异常(Runtime Exception) 和 错误(Error)三类。可查异…...

ShardingSphere|shardingJDBC - 在使用数据分片功能情况下无法配置读写分离

问题场景: 最近在学习ShardingSphere,跟着教程一步步做shardingJDBC,但是想在开启数据分片的时候还能使用读写分离,一直失败,开始是一直能读写分离,但是分偏见规则感觉不生效,一直好像是走不进去…...

char s1[len + 1]; 报错说需要常量?

在C中,字符数组的大小必须是常量表达式,不能使用变量 len 作为数组大小。为了解决这个问题,你可以使用 new 运算符动态分配字符数组的内存,但在使用完后需要手动释放。 还有啥是只能这样的,还是说所有的动态都需要new&…...

【Linux】CentOS-6.8超详细安装教程

文章目录 1.CentOS介绍:2.必要准备:3.创建虚拟机:4 .安装系统 1.CentOS介绍: CentOS是一种基于开放源代码的Linux操作系统,它以其稳定性、安全性和可靠性而闻名,它有以下特点: 开源性&#xff1…...

【Java 进阶篇】MySQL启动与关闭、目录结构以及 SQL 相关概念

MySQL 服务启动与关闭 MySQL是一个常用的关系型数据库管理系统,通过启动和关闭MySQL服务,可以控制数据库的运行状态。本节将介绍如何在Windows和Linux系统上启动和关闭MySQL服务。 在Windows上启动和关闭MySQL服务 启动MySQL服务 在Windows上&#x…...

Android 11.0 mt6771新增分区功能实现一

1.前言 在11.0的系统开发中,在对某些特殊模块中关于数据的存储方面等需要新增分区来保存, 所以就需要在系统分区新增分区,接下来就来实现这个功能 2.mt6771新增分区功能实现一的核心类 build/make/core/Makefile build/make/core/board_config.mk build/make/core/config…...

LiveData简单使用

1.LiveData是基于观察者模式,可以用于处理消息的订阅分发的组件。 LiveData组件有以下特性: 1) 可以感知Activity、Fragment生命周期变化,因为他把自己注册成LifecycleObserver。 2) LiveData可以注册多个观察者,只有数据…...

手动实现Transformer

Transformer和BERT可谓是LLM的基础模型,彻底搞懂极其必要。Transformer最初设想是作为文本翻译模型使用的,而BERT模型构建使用了Transformer的部分组件,如果理解了Transformer,则能很轻松地理解BERT。 一.Transformer模型架构 1…...

Cursor-free-vip:突破AI编程助手限制的技术探索与实践指南

Cursor-free-vip:突破AI编程助手限制的技术探索与实践指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your…...

工程设计类学习(DAY23):智能电表通信接口(RS-485/RS-232/RS-422)防雷击与过电压保护方案深度解析

每日更新教程,评论区答疑解惑,小白也能变大神!" 目录 1. 行业背景与 RS-485 通信技术概述 2. 传统 RS-485 防雷击保护方案及其局限性分析 2.1 传统三级防护电路架构与工作原理 2.2 传统防护方案面临的技术瓶颈 3. 创新防护方案&…...

深度解读谷歌地图Gemini整合:从技术架构看AI如何重构LBS应用

【导语】2026年3月,谷歌地图宣布整合Gemini模型,推出对话式搜索Ask Maps和沉浸式导航。这不仅是产品功能的升级,更是LBS(基于位置的服务)应用与AI大模型深度融合的标志性事件。 自然语言理解如何实现从关键词到复杂意图…...

免费开源+高清无水印!最强录屏神器oCam,大学生和职场人必备效率工具!

前言大家好呀!这里是练习时长两年半的个人练习生Rebirth重,今天又来给大家分享实用工具啦!今天就不跟大家伙聊虚的了,直接给大家上干货,我要介绍的就是录屏工具Ocam!链接:https://pan.quark.cn/…...

C语言中的分支语句

食用指南:本篇文章介绍了c语言中的if、switch分支语句,偏基础向,可用于复习或者初学者自学。--欢迎各位交流--C语言的结构可分为:顺序结构、选择结构、循环结构。我们可以使用if、switch语句来实现分支结构(也就是所谓…...

Vue3集成vue-drag-resize实战:打造灵活可调的DOM拖拽与动态渲染方案

1. 为什么你需要一个“会动”的界面组件? 如果你正在用Vue3开发一个后台管理系统、一个可视化大屏,或者一个类似在线PPT、海报设计这样的工具,那你肯定遇到过这样的需求:页面上有些“小卡片”、“小模块”,用户希望能用…...

VMware与Ubuntu 23高效协作指南:共享剪贴板与文件夹的完整配置流程

1. 为什么需要共享?从“隔阂”到“无缝”的体验跃迁 如果你和我一样,经常在Windows主机上用VMware跑Ubuntu虚拟机做开发或学习,那你一定经历过这种“割裂感”:在主机上复制了一段代码,想粘贴到虚拟机的编辑器里&#x…...

SiameseUIE模型在数据库课程设计中的创新应用

SiameseUIE模型在数据库课程设计中的创新应用 1. 课程设计的痛点与挑战 数据库课程设计是计算机专业学生的必修实践环节,但传统方式存在不少痛点。学生需要从需求文档、访谈记录等非结构化文本中手动提取实体、属性和关系,这个过程既耗时又容易出错。 …...

揭秘租测云租手机让效果翻倍的租赁测试解决方案

揭秘租测云租手机:让效果翻倍的租赁测试解决方案在当今快节奏的商业环境中,如何快速获取最新的智能手机进行测试,成为了许多企业面临的一大挑战。租测云提供的租手机服务,不仅为企业提供了灵活的解决方案,还极大地提升…...

使用Visual Studio2026编译boost库1.90.0

起因 最新在学习boost库的使用,于是就想跟着视频教程在自己本地通过编译boost库,但是我本地安装的是Visual Studio2026,对应的MSVC版本是14.50,boost源码中的b2版本是5.3.2,最高只支持到14.3,导致一直编译…...