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

依赖注入基础

依赖与依赖注入

首先,什么是依赖?
依赖是两个类之间的一种关系,其中一个类使用了另一个类的功能,也就是说,一个类依赖于另一个类。

在 OOP 中,依赖通常以在类中创建实例的形式出现。通过这个实例,一个类可以访问另一个类的方法。这样,类之间就产生了依赖。

例如,下面的伪代码展示了一个依赖关系。在 EmailService() 类中,我们创建了 Email() 的实例:

class Email ismethod sendMessage() is...class EmailService isEmail gmail = new Email()method sendMessage() isgmail.sendMessage()

这里,EmailService 类直接依赖于 Email 类。


什么是依赖注入?

依赖注入(Dependency Injection, DI) 就是把对象创建的任务转移到代码的其他部分。也就是说,把“依赖”作为外部传入的对象来使用。这样做的好处是可以让代码实现解耦合

👉 关于松耦合的好处,可以参考 耦合与内聚(Coupling and Cohesion)

目前并没有一致的观点认为 DI 是不是一种“设计模式”。这里作为入门介绍,解释会比较简化和主观。要更深入理解,你需要进一步学习 控制反转(IoC) 和相关的设计模式。


DI 示例

在第一个代码片段里,EmailService 依赖于 Email 类。因为它在类内部直接创建了 Email 实例,所以你无法切换不同类型的 Email 实现,也无法方便地测试。

为了解决这个问题,我们来看看使用 DI 改写的方式:

interface Email ismethod sendMessage()class GmailService implements Email ismethod sendMessage() is ......class EmailService ismethod sendMessage(Email service) isservice.sendMessage()

这里的变化是:

  • EmailService 依赖的是 接口 而不是具体类。

  • Email 接口可以有多个不同的实现,比如 GmailService

  • 对象的创建被移到了其他地方。

这样,我们就可以灵活地选择不同的实现:

EmailService gmail = new EmailService()
gmail.sendMessage(new GmailService())

依赖注入的三种方式

依赖注入主要有三种常见方式:

1. 方法(接口)注入

依赖通过方法传递进来。上面的例子就是方法注入。


2. 属性(Setter)注入

依赖通过单独的 setter 方法 注入。不同语言的实现方式可能不同,这里给出最简单的伪代码:

class EmailService isEmail servicemethod getService() isreturn servicemethod setService(Email service) isthis.service = serviceclass Main isEmailService email = new EmailService()email.setService(new GmailService())Email gmail = email.getService()gmail.sendMessage()

在 Java 中,配合 Spring 注解,你可以从配置文件里把参数注入到 set 方法里。


3. 构造函数注入

依赖通过类的构造函数传入:

class EmailService isEmail emailconstructor of EmailService(Email email) isthis.email = emailmethod sendMessage() isemail.sendMessage()class Main isEmailService gmail = new EmailService(new GmailService())gmail.sendMessage()

为什么需要依赖注入?

依赖注入的核心目的就是 降低耦合度
通过 DI:

  • 我们可以把对象创建的工作交给外部,不需要在类内部硬编码实例化过程。

  • 一个类对另一个类的创建过程一无所知。

  • 可以在不修改类本身的情况下重用它。

这对 代码扩展、修改、测试 都非常有帮助。
尤其是测试时,你可以传入不同实现或不同参数,模拟各种情况。

不过,DI 也有一些缺点:

  • 学习曲线陡峭。

  • 使用不当可能导致过度复杂化。

  • 在不同框架和库中的实现方式可能各有不同,带来额外难度。


总结

  • DI 的核心目标:降低耦合度。

  • 优点:提高代码灵活性、可扩展性,简化测试。

  • 缺点:实现较复杂,存在学习成本。

  • 实现方式:方法注入、Setter 注入、构造函数注入。

  • 不同语言/框架的差异:实际实现会有区别。

虽然依赖注入一开始看起来比较复杂,但你现在已经了解了它的基本原理和作用。要更深入,可以继续学习 IoC 和相关的设计模式。


文章转载自:

http://qQUPwRi3.pyLpd.cn
http://aa7rsCUT.pyLpd.cn
http://D8rDH1A2.pyLpd.cn
http://OKXBTiHo.pyLpd.cn
http://iJHjvTzi.pyLpd.cn
http://D2WmNxVf.pyLpd.cn
http://z5tk7R85.pyLpd.cn
http://Zdxxjdcu.pyLpd.cn
http://2f7gSA2w.pyLpd.cn
http://1MrEVZhV.pyLpd.cn
http://xUWZWqmZ.pyLpd.cn
http://BJz9A64d.pyLpd.cn
http://spl1uLLL.pyLpd.cn
http://bHVabsm0.pyLpd.cn
http://zPZfcq4z.pyLpd.cn
http://bo1FLvM9.pyLpd.cn
http://EZfR9o6v.pyLpd.cn
http://62S8bH2D.pyLpd.cn
http://GInDFoiw.pyLpd.cn
http://Xm42Ijz7.pyLpd.cn
http://a4pLRUuR.pyLpd.cn
http://tUTlIMYh.pyLpd.cn
http://jtPZuf1D.pyLpd.cn
http://rk0065AN.pyLpd.cn
http://5zwe6T2O.pyLpd.cn
http://7K6zIufn.pyLpd.cn
http://wOrcrOYX.pyLpd.cn
http://2EonKBLK.pyLpd.cn
http://A7sZExGt.pyLpd.cn
http://cLtilllu.pyLpd.cn
http://www.dtcms.com/a/387929.html

相关文章:

  • 代码随想录二刷之“图论”~GO
  • 基础数学转金融数学考研:一场需要清醒规划的转型
  • Alpha World携手非小号Talking Web3,海上ALPHA WEB3派对启航
  • Vue3钩子,路由拦截实现
  • 数据结构七大排序算法模拟实现性能分析
  • vue+react笔记
  • springboot获取wav文件音频长度
  • 【Redis】-- 缓存
  • 鸿蒙高效数据处理框架全攻略:缓存、并行与流式实战
  • 全网首发! Nvidia Jetson Thor 128GB DK 刷机与测评(五)常用功能测评 - RealtimeSTT 音频转文本 同声传译
  • OpenHarmony 之生态规则管控服务(Ecological Rule Manager Service)源码深度解读
  • 无人机图传是什么意思 应用和趋势是什么?
  • arm coresight
  • Vue3 + vue-draggable-plus 实现可拖拽的数据源选择面板
  • Vue 项目主题切换功能实现:两种方案详解与选型分析
  • 有些软件要求基础环境包含oneAPI组件时带有小版本怎么解释
  • Vue3 基础
  • 处理Element ui输入框类型为Number的时候,中文输入法下回车光标聚焦到了左上角
  • 企业级容器技术Docker 20250917总结
  • 智能艾灸机器人:科技激活千年养生智慧,开启中医现代化新篇章
  • Docker 镜像瘦身实战:从 1.2GB 压缩到 200MB 的优化过程——多阶段构建与 Alpine 的降维打击
  • Unity 性能优化之道(性能问题定位 | 渲染流程分析 | SSAO项优化 | AA优化 | 后处理优化)
  • 进阶内容——BYOT(自带模板,Bring Your Own Template)(99)
  • 算法 七大基于比较的排序算法
  • DeepSeek 分布式部署,配置
  • 蓝凌EKP产品:AI 高效汇总意见,加速决策落地​
  • 在三台GPU服务器上部署分布式deepseek
  • Cpptraj 终极指南:从入门到精通
  • Project Treble和HAL架构
  • 【Linux网路编程】传输层协议-----TCP协议