写点什么

依赖注入是否值得?

  • 2007-12-14
  • 本文字数:1552 字

    阅读完需:约 5 分钟

在博客的世界里进行了一场关于使用依赖注入(DI)之优点和缺点的有趣讨论。论题是:依赖注入是否真的值得?

讨论始自 Jacob Proffitt ,他撰文解释他的观点说,依赖注入的伸缩性不好。据 Proffitt 认为,DI 流行的唯一原因是 Mocking。

DI 进来这么流行的真实原因,和正交性、封装性或者其他“纯粹的”架构考量都没有关系。真正的原因是很多开发者都用 DI 来帮助使用 Mock 对象进行单元测试。随你怎么说,这个因素实际上说服了聪明的开发者选择 DI 而不是更简单的实现。

Proffitt 甚至声称 DI 只对单元测试有好处:

不管怎样,我真的希望人们能够承认 DI 除了单元测试之外,没什么其他有说服力的应用。

不过,Proffitt 虽然做单元测试,却不用 DI。他使用 TypeMock 框架。这个框架可以拦截对依赖对象的调用,哪怕依赖是在被测试代码中创建的。这意味着 Proffitt 不用解耦他的对象也能为单元测试创建 Mock。

Ayende RhinoMocks 的创造者,他在自己的博客上回应说

虽然能够方便地编写 Mock 代码是很棒的特性,但这只是主要利益之外的附带好处,主要的利益是降低了对象间的耦合。我可以修改数据访问部分的代码,而不需要触及负责工资计算的引擎,这是我得到的主要益处。

Nate Kohari 也回答了 Proffitt 的原帖。Kohari 不但给出了一个 DI 的代码示例,还详细阐述了什么是真正的 DI

如果你是 GoF 的爱好者,这其实就是 Strategy 模式。依赖注入(按照我的观点)本质上是大规模使用的 Strategy 模式。

Kohari 是 NInject DI 框架的作者,他强烈反对 DI 框架无用的说法:

一旦你开始倚靠 DI 框架来编写代码,连接对象所需的代价就下降到接近于零。于是,要想达到单一职责的目标,其难度会指数级地下降。

在随后的帖子中,Kohari 重申了使用框架的重要性,以此来回应Proffitt 原先认为 DI 的伸缩性不佳的说法:

在真实世界的使用场景中,手工进行的依赖注入的确伸缩性不佳。

Proffitt 不同意:

你怎么能说依赖注入(我不是针对整个控制反转模式,但也未尝不可。只是还没轮到。)创造了易于复用的松散耦合的单元?DI 本身就要求调用者去提供被调用者的所需。任何理性的评价都会认为这是提高了耦合程度。把耦合的负担丢给框架并不能改变事实,使用一个对象,仍然需要先给它提供外部的东西。

Kohari 解释在大多数情况下,如何创建和注射特定类型的对象只需要配置一次,而且是由框架完成的,不是由调用者。

Kohari 还谈到了代码的变化能力:

……简单来说,依赖注入让你的代码更容易改变。这就是它在敏捷社群中流行的原因,他们的整个软件开发实践都围绕着快速变化。

Eli Lopian 是设计出 TypeMock 的公司的 CTO 也加入争论,他对争论的核心有不同的看法:

当你把 DI 当作是“银弹”来使用,你就丧失了所用编程语言的一大半能力。你不能用静态方法,不能用“new”关键字,不能用封闭类型。哦,你还要把所有的方法都变成虚拟的。

他还争辩说,仅仅为了方便变化而使用 DI,违背了 YAGNI 原则

Lopian 继续说:

TDD 刚兴起时,首先被讨论的一个问题就是“我们是否应该修改代码来满足可测试的要求?”我们应不应该改变代码的可见性?我们应不应该改变代码的设计?这个问题导致了可测试的代码与 OO 封装性之间的冲突。开发者们开始为了能够测试,而把代码中的私有部分暴露出来。开头只是私有方法和属性,现在扩大到了整个设计。

这是一个老问题了。有些人认为改变代码让它更容易测试是一件好事;其他人认为这样做打破了封装性,因此是坏事。

Kohari 对封装与依赖的的关系提出了看法:

这是让依赖注入物有所值的秘密:当谈到依赖的时候,封装是坏的。

如果出于单元测试的意图而改变代码,能让耦合变得更松散(Proffitt 对此有所质疑)——这是不是一件好事呢?

松散耦合与封装都是重要的 OO 特征,那我们如何作出平衡呢?哪条路才是对的?

查看英文原文: Does Dependency Injection pay off?

2007-12-14 04:204851
用户头像

发布了 225 篇内容, 共 74.8 次阅读, 收获喜欢 53 次。

关注

评论

发布
暂无评论
发现更多内容

复习54天二战字节跳动,终获offer定级2-2【面试答案,springboot底层原理面试题

Java 程序员 后端

大厂面试题:有了G1还需要其他垃圾回收器吗?我教你怎么答

Java 程序员 后端

三面阿里被挂,竟获内推名额,历经5面拿下口碑offer(Java后台)

Java 编程 程序员 架构 面试

图解Redis:一套方案轻松搞定数据库与缓存数据不一致问题

Java 程序员 后端

NQI一站式线上平台搭建,质量基础设施一站式服务

电微13828808271

大厂面试算法到底有多重要?学会这份算法宝典,随便暴打头条面试官

Java 程序员 后端

图说线性表-搞懂链表从这篇文章开始,2021必看-Java高级面试题总结

Java 程序员 后端

基于springboot开发的国际物流管理系统,花费近一年时间整理的Java核心知识清单

Java 程序员 后端

在外包公司从Java后端干到安卓开发,你醒醒吧!,阿里大师推荐的这份Java开发必读书单

Java 程序员 后端

基于Java NIO框架区别对比,spring教程下载

Java 程序员 后端

团队管理(二)-敏捷开发最佳团队协作管理平台,mysql入门很简单视频

Java 程序员 后端

架构实战营总结

Mr.He

架构实战营

基于DRBD的KVM动态迁移,Java开发需要学什么

Java 程序员 后端

多线程—可能你会遇到的多线程面试题都在这里了(含答案

Java 程序员 后端

大厂面试题中爱问的「调度算法」(1),java后端技术栈图谱

Java 程序员 后端

四面美团开发岗,成功斩获offer,这份面经总结终结篇看完就是血赚

Java 程序员 后端

图解Redis数据结构篇之压缩列表,java注解原理解析

Java 程序员 后端

社招三面阿里“落榜”,幸获内推名额,4面揽下美团offer

Java 架构 面试 后端

四年的开发经验只去面试了蚂蚁金服,无忧一次过,自学linux视频教程推荐

Java 程序员 后端

国内顶级大牛整理:分布式消息中间件实践笔记+分布式核心原理解析

Java 程序员 后端

备战金三银四吃透这些Spring Boot笔记文档,让你超过90%的Java面试者

Java 程序员 后端

多线程详解第3讲:线程状态,感悟分享

Java 程序员 后端

大厂面试官:千万级数据量的表,如何进行快速查询,springmvc源码书籍

Java 程序员 后端

嘘,助你一臂之力,快来瞧瞧这份-Spring-面试小抄,百度语音识别接口java

Java 程序员 后端

团灭LeetCode!Alibaba技术官甩出的大师级算法宝典真的太香了!

Java 程序员 后端

图解Redis:一套方案轻松搞定数据库与缓存数据不一致问题(1)

Java 程序员 后端

在SQL SERVER中实现RSA加解密函数,java入门书籍推荐

Java 程序员 后端

基础面试3:内存溢出 vs 内存泄漏,java自学教程视频

Java 程序员 后端

堪称零瑕疵!仅用了330页直接封神,我要吹爆这份RocketMQ笔记

Java 程序员 后端

质量基础设施一站式平台建设,NQI一站式系统开发

电微13828808271

大厂面试题中爱问的「调度算法」,分享一波阿里、字节、腾讯、美团等精选大厂面试题

Java 程序员 后端

依赖注入是否值得?_.NET_Niclas Nilsson_InfoQ精选文章