想讨论一下阿里开源的 Go 的 IoC 框架以及 Go 是不是真的需要 ioc

2022-06-28 10:33:21 +08:00
 Sunxy88

本人之前写 Java ,目前是 Go 语言新手。

前不久阿里开源了一款 Go 的 IoC 框架,由此引发我的好奇。搜索了一下发现 Go 还存在挺多 IoC 框架的。 只是作为新手有点好奇,面向过程语言真的需要 IoC 吗?

我理解是 Java 有 Spring 是因为它是纯面向对象的,没有函数这个概念只有方法,所以在一些需要函数的地方就需要通过 IoC 来注入一个单例。我作为使用者感觉到的是,IoC 是面向对象语言对于一些无状态的逻辑的妥协。

但是像 Go 这种面向过程的,不是就直接调用那个函数就好了吗?真的需要将 Go 写成 Java 的样子吗?

还请各位指点一下新人,提前感谢!

8004 次点击
所在节点    Go 编程语言
55 条回复
wangyzj
2022-06-28 18:54:18 +08:00
@Saxton #26 IoC 是什么不需要你来强调
如果你想理解我说的具体啥意思,请看 #29
charlie21
2022-06-28 19:51:41 +08:00
关于依赖注入的一篇文章 为什么有很多人说 Go 语言不需要依赖注入? golang
https://www.zhihu.com/question/265433666/answer/337599960
依赖注入,可说是任何程序员必掌握的技巧之一,系统设计入门基础技能之一。而依赖倒置原则作为一条原则,自从被人发现以来,从来都没被颠覆过,可以算得上软件设计艺术的真理之一。
securityCoding
2022-06-28 20:22:54 +08:00
多用用 interface ,mock 起来不要太爽,至于 ioc 可有可无
iosyyy
2022-06-28 20:26:50 +08:00
@cheng6563 简洁是指 err 漫天飞吗..
@GeruzoniAnsasu "静态语言都不热衷这种框架" 你知道 ioc 起源自哪里吗? 起源自 cpp 最经典的静态语言 另外你举这个例子本身就不符合开闭原则程序更改只能对内进行更改 但是引入 xml 文件程序更改就是对外的了 因为配置文件可以理解为程序外部的一部分 你觉得是更改一个 xml 中一个字段容易呢 还是几千行代码里面改一段不知道哪个函数里面的代码容易呢?(这里我还是想说尤其是在 go 语言 err 满天飞的情况下). 另外关于屎山的观点 诚然程序写多了会导致系统有很多"奇奇怪怪"的代码 但我们要做的是避免这些的出现 不能因为屎山能跑就一味的拥抱她 虽然程序总会化为屎山但是我们写的代码是可能变成屎山里面的黄金的代码与方法从来都是我们在用而不是乃作屎山
iosyyy
2022-06-28 20:28:35 +08:00
@iosyyy 就像楼上的文章中说的"一个语言只能说需不需要什么功能,而依赖注入是架构,不是功能。"
cheng6563
2022-06-28 22:21:12 +08:00
@iosyyy 简介说的是编译流程,直接官方工具就能一步编译,不用搞一大坨工具链。
GeruzoniAnsasu
2022-06-28 22:36:55 +08:00
@iosyyy CRTP 是一个经典又独特的 idiom, which 完美体现了「反转」是怎么一回事,但 cpp 哪个项目试图把 spring 那一套在 cpp 上重新造一次吗? 就算我孤陋寡闻没听说过「可能被拿出来举例的项目」,但那个项目——它不流行吧?也不在 cpp 的主流视野里吧?


你看了知乎,也看了阿里这个框架想干什么的话就会明白我说的「拿锤看钉」是什么意思,就跟在 cpp 里写
template<class T, class F > class IoCContainer{std::variant<T> obj}
class MyService : public IocContainer<MyService, Feature<Service, AutoWire>> {}
一样,也不说徒劳吧,反正看着滑稽是肯定的,因为 cpp 里模板参数本身就可以当成接口来用,根本没必要去模拟注解的功能,也模拟不来,顶多仿照一个静态版本——而静态版本↑模板参数本身就可以当成接口用,service 的使用者只要写
template<class S> class UsingService{}
然后在 UsingService 实例化的地方(而非 UsingService 内,UsingService 并不直接依赖 Service ,而是自己的模板参数)给 UsingService 派发 MyService 就好,这本身就是 IoC 作为设计原则的体现,而非造一个看起来像 spring 的框架,那根本就不合适啊。


另外开闭原则指的是(广义版)逻辑模块的开闭,你这直接把整个程序都看成不可分割的一个大逻辑块的看法整得我有点无语
24bit
2022-06-28 23:00:19 +08:00
在我看来 Java 中的 DI 是转移复杂度的一种方式,将 Bean 的装配转移到框架完成,开发者只需要标记需要什么 Bean 就行了。

Java 纯 OOP 的设计会导致项目中存在大量的类和接口,同时会创建出大量的 Bean ,手动装配这些 Bean 是一件很费事的事情,因此使用 DI 是很有效的转移复杂度,减负增效的方式。

而 Golang 虽然支持一定的 OOP 特性,但中小型项目中类似 Java 中需要装配大量 Bean 的场景并不是很多,引入基于代码生成或反射的 DI 框架会反而会带来额外的成本,增加复杂度。

Golang 本身是一个「简陋」的语言,硬是往 Java 的模式上靠往往会带来额外的复杂度。
CoderGeek
2022-06-28 23:44:31 +08:00
@Abirdcfly Uber 内部就是 fx 主要是作统一资源的加载 上面说的放在 context 是常见的,
起码写 mock 和替换会更合理也集中管理了
我也是新手但说实话看着那一堆代码很累
iseki
2022-06-29 02:17:58 +08:00
还没有去看这个东西,只说下个人感觉。IoC 需要但 IoC 框架之于 Go 可能有点重了。
IoC 是个思想自不必说。但 IoC 框架··· 这种框架用来在大量使用此类范式时降低人的工作量,但是 Go 是一个动态性不足的语言,和 Java 那种动不动运行时动态字节码生成不同,基本没法这么干;其次静态连接的 Go 也很难像经典 Java 一样根据配置随时加载不同的依赖项,像 Java 那样大规模 IoC 并不会有特别多的好处,是否需要为了解决一点问题而引入一整个框架存疑。
tairan2006
2022-06-29 08:45:44 +08:00
DI 还是需要的,抽象接口多重实现。不过我一般都是手动注入的,小项目没必要搞个框架。

大项目可能需要一套吧,或者考虑微服务拆分?
iosyyy
2022-06-29 12:27:36 +08:00
@GeruzoniAnsasu 不流行? 不流行从来就不代表不行 cpp 主要是写内核系统这种要求速度快的程序的 像 linux 代码中一大堆 goto 你能说 goto 就是好东西?? 另外开闭原则指的是"软件中的对象(类,模块,函数等等)"对修改关闭对扩展开启, 从来就不是你说的对于逻辑模块 这属于偷换概念 而且代码什么时候不是逻辑模块了呢? 另外 ioc 从来都不只是 spring 你上面提出的观点也是对于 ioc 本身而不是 spring 和楼主提出的阿里框架
GeruzoniAnsasu
2022-06-29 14:58:59 +08:00
@iosyyy 你擅长记概念这点我看出来了

那么我替你总结一下你表达过的观点
1. cpp 也有 ioc 框架
2. 改代码不符合开闭原则但改 xml 符合
3. 不要屎山
4. 不流行的做法不代表 bad practice

噢…… 除了第二点不同意其它的我同意啊

所以为啥要有个像 spring 的框架呢,它会好用吗?


OP:
> 真的需要将 Go 写成 Java 的样子吗

#29 :
我的观点是作为一种指导思想,在不同语言里有适合各自的表达形式,复制一个相似的框架并不能起到足够引人注目的效果,而且同一种设计在不同语言机制下能带来的意义也不同。因此我认为不需要或者不应该把 go 写成 java 的样子。

上述观点我后来又重复地显式地总结了一次

#47 :
> … 本身就是 IoC 作为设计原则的体现,而非造一个看起来像 spring 的框架,那根本就不合适啊



这一点我们共识吗?
izzy27
2022-06-30 00:01:17 +08:00
写得 go 不多,但是目前的认知觉得 go 并不需要 spring 这种 IOC 框架
ecnelises
2022-07-02 01:57:21 +08:00
想起一个笑话:

为什么 C#里没有 Spring ?因为微软没有春天。

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

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

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

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

© 2021 V2EX