19 条回复  ·  2100 次点击
xiuming 小成 2024-12-4 13:33:28
@matrix1010 就是有人新语言 用旧思想写代码
fgwmlhdkkkw 小成 2024-12-4 13:35:28
整个全局指针不就行了吗……
sophos 小成 2024-12-4 13:36:38
可以看看我这个项目 :-) - https://github.com/go-kod/kod - https://github.com/go-kod/kod-mono - https://github.com/go-kod/grpc-gateway
rrfeng 小成 2024-12-4 13:37:08
k8s 有依赖注入吗?
xiuming 小成 2024-12-4 13:37:51
还要是理解 go 语言编程思想,Java 有 Java 编程思想没问题,可别把别的语言编程思想套到另一个语言,会很别扭很难受的。
sophos 小成 2024-12-4 13:39:54
哈哈哈,审错题了,不好意思
kuanat 小成 2024-12-4 13:49:29
我觉得需要重新描述一下,区分依赖注入和依赖注入框架。对 Go 来说,依赖注入几乎无处不在,但没有使用任何依赖注入框架的必要。 一时半会想不到特别合适的开源项目,我就尝试描述一下做法。正文里提到了依赖注入的两个场景,一个是被动初始化,另一个是单元测试。这两个都可以用接口 Interface 来完成,方法也是一样的。 标准库里有非常多传递实例的写法,比如传一个 *http.Client 这样。如果需要多个不同组件按照特定顺序初始化,可以直接用 struct embedding 把各个实例封装起来,然后就可以传递 struct 了。 因为我的组里有很多其他背景的开发者转型而来,对于传递 struct 的做法不认可,主要的理由是他们都有要初始化几十个依赖的经历。我对此的观点是,某个组件依赖几十个其他组件这件事本身就有问题,即便是真的有很多依赖,也只是依赖其中非常小的功能而非全部。我个人认为造成这种结果的原因是用基于 class 实现的继承去套用 Go ,而 Go 的做法是完全不实现继承功能,通过组合来抽象 OO 。 第二个需求单元测试需要对代码做调整,或者说对编程思路做调整。之前我在别的 Go 语言讨论帖子里反复引用过 Accept interfaces 这个说法,如果将调用方的代码依赖从实例改成接口,就可以非常简单地实现 mocking 来做单元测试。 因为调用方无须关心调用的是哪个实例,只要这个实例实现了特定的接口即可。将调用方的方法改写为接收接口,就可以用任意的实现来 mocking 对应的功能。 如果把接口当作继承来用,那自然就会觉得依赖是个复杂的事情,因为这个接口会越来越大,最终变成了模块之间的强耦合。实际上 Go 的思维里,接口越小越好,这里的思想是组合而非继承。一个非常小的接口是很容易 mocking 的。 另外如果观察一下 github 上 Go 的 DI/mocking 相关的项目也能发现一个趋势,相比其他语言这两种框架几乎都不流行。因为真的没有必要。不过反过来说,接口就是依赖注入。
houshuu 小成 2024-12-4 13:53:57
公司内部有不少,但是没有外网链接。体感 用 DI : 不用 DI = 7:3 的样子。 如果业务逻辑非常简单,依赖非常清晰,没有什么分岔的话,其实用不用 dig 写起来差不多的。个人经验来说依赖注入在 Go 大部分情况下都是伪需求或者说提升编码效率的小工具,开始的时候没用的话不必要强上。要跨组件公用的话,直接暴露一个变量或者一个 getter ,内部用 once 啥的初始化一下就行。 单元测试要补强的话,在写的时候就一定要习惯用 interface 来声明组件,方便之后 mock 。(当然另一个方面来说,Interface 写多了,用 DI 自动串起来还是挺方便的。)说实话每次写单元测试都感觉挺不 Go 的,还是 Java 那套思路。但是回头想想,非常多单元测试实际上没有任何作用,只是单纯提升 coverage 而已。现在我比较喜欢把核心逻辑去掉各种 side effect 抽到某个函数里,然后对函数做比较多的 UT ,其他 side effect 直接交给后面的 e2e 什么的来验证。还是要具体情况具体分析,避免无效工作。
matrix1010 楼主 小成 2024-12-4 14:04:56
@kuanat 几十个可能不多,但 初始化十几个个依赖 还是很容易出现的,特别是复杂度很高,多人协作,质量管理不太严格的大型项目上。只能接受而没法改变的情况下依赖注入框架就很方便。interface 方便单元测试 mock 是肯定的,我做的第一轮重构就是这个
matrix1010 楼主 小成 2024-12-4 14:09:41
@houshuu 其实只要你把依赖传入就是 DI ,不用 DI 的话就只能每次需要就 New 一个。在多人协作的情况下看似没用的单元测试有可能会在你意想不到的地方起作用
12
返回顶部