大家有没有见过没有使用依赖注入的复杂 Go 开源项目

36 天前
 matrix1010

最近打算把公司的项目重构为使用依赖注入初始化所有服务(现在是每次需要某个依赖就内部 New 一个), 想找一些开源项目作为例子。但是简单找了找都是自动/手动进行依赖注入的,大家有没有见过 没有 使用依赖注入的:

5868 次点击
所在节点    Go 编程语言
95 条回复
grzhan
36 天前
就我所知绝大部分 Golang 开发的偏基础设施与中间件的大型项目( Kubernetes 、VictoriaMetrics……),以及包括 Go 语言 Runtime/Compiler 本身都没有使用 DI 框架。

所有的依赖都是自己手动处理的,通过一系列的 NewXXX 函数以及工厂方法。很多 struct 可能就是全局的,在 go 启动时候就创建起来,然后在 package 范围内可见。在一些场景里可能会用一个比较大的叫做 "xxxCtx" 的上下文 struct (注意这个只是 struct 起了个名字,而与 context 标准库无关),用来维护传进来的 dependencies ,供这个上下文的方法使用,对于内部的 struct 有点像一个 DI 容器吧,但这个 "DI 容器"的依赖本质还是自己维护的。

个人觉得手动管理依赖并不是邪恶的,Go 的隐式接口实现可以做到不少代码较好的解耦(虽然隐式接口实现有单独的槽点),Go 项目里这些 struct 的设计也大部分实现了依赖注入模式(构造函数注入、方法注入),足以支撑复杂的项目。

然后 Go 项目很少使用 DI 框架,这样大型项目手动维护一个 "Unit" 几十上百个依赖是不是太麻烦了?事实在于,Golang 这些项目的开发者不少都认为一个"Unit" 不应该和所有依赖进行交互,而应该专注于具体的事情,去看这些项目的 struct ,他们的依赖基本上也是可控的,大部分都是最最多十几个这样了。如果一个组件依赖过多,可能需要思考是不是该重构了。

当然对于大规模多人的业务需求迭代频繁的大型 Web 应用项目,我觉得依赖注入 DI 框架还是有价值的,因为这种迭代变化频繁的项目可能会有很多业务驱动的 Service ,用 DI 框架能够提升开发效率,让搬砖的 IT 民工(比如我)不需要关注很多细节,但另一方面微服务模式一定程度上也降低了单体的复杂度,缓解了此类问题
securityCoding
36 天前
go 可读性这么好的语言手动构造器注入吧
CLMan
36 天前
虽然很多人答非所问,但是也侧面说明了:楼主为啥会问这么奇怪的问题,感觉就像熟读技术书籍但没写过一天代码的怪人。
Meld
36 天前
>>> 大家有没有见过 没有 使用依赖注入的

Has anyone seen anything that does not use dependency injection?
grzhan
36 天前
感觉我确实答非所问了( x
不过要找一个**真正没有使用依赖注入模式**的 Go 复杂项目感觉还挺难的
gl3081
36 天前
依赖注入对于模块化开发来说非常灵活方便,尤其是微服务架构,具体实践可以参考我的开源项目: https://github.com/moke-game/platform
zhady009
36 天前
@Orenoid 我也没看懂这东西跟 Java 就没啥强关联,还有把依赖注入说成臭不可闻的
RayR
36 天前
@zjsxwc #35 忘记官方是不是有过建议不要用 init (也有可能是某个博客的观点)。实践中多个开发维护一个项目出现 import 顺序被修改造成初始化错误的情况。
lizy0329
36 天前
Go 是函数优先的强类型语言,不需要 Java 的正畸辅助道具
mrjnamei
36 天前
还是不要的好。目前在写的项目用的是 fx ,new 一个 service 十几个依赖的情况写的非常难受:

注入:
fx.Provide(NewApplicationService)

构造:
func NewApplicationService (
depend1 SomeService1,
depend2 SomeService2,
depend3 SomeService3,
depend4 SomeService4,
depend5 SomeService5,
depend6 SomeService6,
depend7 SomeService7,
depend8 SomeService8,
) *ApplicationService {
return &ApplicationService {
depend1: depend1,
.....
}
}

不使用这种传参的注入方法可以直接 New, 写起来舒服一些.
matrix1010
36 天前
@mrjnamei 其实这个 NewApplicationService ,完全可以把 struct 扔给任何 AI 来写. 这种极简单场景我估计任何 AI 都能达到几乎 100%准确率
xz410236056
36 天前
@matrix1010 #23 你发的这不都是 java 的吗(包括该问题下的其他讨论),层主说的就是你别用 java 的思想写 go 啊
godlovesxcjtest
36 天前
james122333
36 天前
Go 有依赖注入 但我也不喜欢依赖注入
首先依赖注入是非常割裂的 在 java 上就很少看到集中一处统一管理的 搭配注解也更难釐清依赖关系 外加很多东西根本没有善用命名空间
很多第三方库都是乱七八糟 一个命名空间一个 package 负责一项功能更利于管理 整个架构就会很漂亮 也更好做複杂功能 方便掌控全局代码
依赖注入本身就很有阴谋味 职场的效应很明显
不论是挖坑给别人还是代码只有自己能看懂都是暗黑优势 但还是有不少人只是想安静的搬砖
james122333
36 天前
@gl3081

命名空间就是在做模块化这种事了
gogogo1203
36 天前
想吐就看 mattermost , 想看清晰架构 就看 https://github.com/ardanlabs/service. 我 n 年没有写 go 了,不过这两个 repo 还是牛的。
pkoukk
36 天前
@Jinnrry 依赖注入和依赖注入框架是两回事,不搞依赖注入,你咋做单测啊?
pkoukk
36 天前
不用框架,手动注入
设计合理的话问题不大,AI 能写 99%,约等于自动注入了
pkoukk
36 天前
@zjsxwc #35 init 从来不建议做初始化依赖这种事情,因为它的顺序难以保证,理论上 init 里应该只有自己 package 内部的东西
james122333
36 天前
@pkoukk

命令行参数透过反射呼叫阿

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1094915

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX