写点什么

依赖注入是否值得?

  • 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:204798
用户头像

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

关注

评论

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

YashanDB逻辑运算符

YashanDB

数据库 yashandb

YashanDB constraint语法

YashanDB

数据库 yashandb

macOS Sequoia 15.4 (24E248) Boot ISO 原版可引导镜像下载

sysin

macos

如何快速搭建自己的个人网站?Hexo、VuePress 和 WordPress 大比拼!

程序员晚枫

从“新农人”到“买菜团长”,拼多多激发电商就业生态二次繁荣

Alter

电商新趋势,从“真人一键克隆”数字人进军直播间开始

脑极体

AI

JVM实战—JVM垃圾回收器的原理和调优

不在线第一只蜗牛

JVM

MobPush用户分群功能全新升级,精准触达每一位用户

MobTech袤博科技

消息推送 mobpush 消息推送系统

YashanDB比较运算符

YashanDB

数据库 yashandb

YashanDB算术运算符

YashanDB

数据库 yashandb

YashanDB RegExp语法

YashanDB

数据库 yashandb

a16z合伙人:语音交互将成为AI应用公司最强大的突破口之一,巨头们在B2C市场已落后太多丨Voice Agent 学习笔记

声网

YashanDB compile_clause语法

YashanDB

数据库 yashandb

macOS Sonoma 14.7.5 (23H527) Boot ISO 原版可引导镜像下载

sysin

macos

全链路、全通道、多维度,MobPush后效折损分析功能确实太全面了

MobTech袤博科技

消息推送 mobpush 消息推送系统

YashanDB位运算符

YashanDB

数据库 yashandb

YashanDB连接运算符

YashanDB

数据库 yashandb

MobPush智能消息推送能力大集结,国内外消息触达通道来了!

MobTech袤博科技

消息推送

2025 程序员必看:用这 3 个 AI 工具,接私单效率翻 3 倍

飞算JavaAI开发助手

MobTech受邀出席鸿蒙生态伙伴SDK开发者论坛

MobTech袤博科技

鸿蒙 os

MobTech受邀出席年度DevFest 谷歌开发者节

MobTech袤博科技

消息推送 消息推送系统

YashanDB dblink语法

YashanDB

数据库 yashandb

2025首批!腾讯云AI代码助手斩获信通院可信AI智能编码工具最高等级认证!

CodeBuddy

AI

没有数据湖?可观测性也许不再有效!

观测云

数据湖 可观测性

SLS 重磅升级:超大规模数据实现完全精确分析

阿里巴巴云原生

阿里云 云原生 日志服务

高配置的七彩虹将星X18 Max游戏本来了,来打造专属你的电竞之夜!

E科讯

百度推出端到端语音大模型,支持方言、可打断、电话语音成本砍半;雷神 AI 眼镜发布:语音助理+摄像头,1799 元起丨日报

声网

迈向云原生:理想汽车 OLAP 引擎变革之路

镜舟科技

大数据 云原生 OLAP 镜舟数据库 理想汽车

RAG 调优指南:Spring AI Alibaba 模块化 RAG 原理与使用

阿里巴巴云原生

阿里云 云原生 云原生微服务

局域网视频软件BeeWorks Meet,企业内部安全会议不断线

BeeWorks

即时通讯IM 私有化部署 企业级 局域网视频软件

YashanDB condition语法

YashanDB

数据库 yashandb

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