一次 GO 项目重构的疑问

2024-03-06 09:38:13 +08:00
 yujianwjj
type A struct {
   a ComponentA
   b ComponentB
   d ComponentD
}
func NewA(a ComponentA, b ComponentB, d ComponentD) {}
type B struct {
   b ComponentB
   c ComponentC
   d ComponentD
}
func NewB(b ComponentB, c ComponentC, d ComponentD) {}


// 大概有十几个这样的 struct
....

这十几个 struct 都有一些共同的变量(当然也不是完全一模一样)。 现在是每个结构体的 New 方法传的参数都不一样。当然这十几个 struct 其实做的功能比较相似(每个 struct 其实是 k8s 里面 crd 的 controller ),代码结构也有一定的相似性。

现在重构后的代码

type Common struct {
   a ComponentA
   b ComponentB
   c ComponentC
   d ComponentD
   // 一共大概 20 几个
   ...
}

type A struct {
    *Common
}
type B struct {
    *Common
}

这样重构后,每个结构体的 New 方法的参数就很简单,只要传一个 Common 就好了。 但是,这样每个结构体其实引入了一些自己不需要的东西,我自己感觉不是特别好。

各位大佬怎么看?

3475 次点击
所在节点    Go 编程语言
21 条回复
NessajCN
2024-03-06 09:46:03 +08:00
别 func New 了,go 里直接就能 newA := A{a,b,c}
zzhaolei
2024-03-06 09:46:13 +08:00
用 wire 或者 fx 做依赖注入
vczyh
2024-03-06 09:47:04 +08:00
struct 你要有实际意义,common 这种模糊的东西最好去掉,看似提出公共东西了,但是一点也不好维护,不同的东西就是应该分成多个 struct ,要是你觉得一样那就重新思考到底是不是不同的东西,如果是那就分开好了,成员变量相似又不是相同。
vczyh
2024-03-06 09:49:21 +08:00
@NessajCN 你没想过变量的可访问性?
Reficul
2024-03-06 09:49:57 +08:00
感觉还不如之前的,你要是嫌麻烦可以用 Wire 这样的 DI 工具。
jrqlxue
2024-03-06 09:53:42 +08:00
从写代码的角度,我肯定更喜欢一个 Common 搞定。
以及更激进些,ComponentA ComponentB ComponentC ComponentD 是否能合并成 Component 呢😁
8355
2024-03-06 09:55:14 +08:00
习惯开发弱类型语言脚本语言的老毛病了
现在这种重构之后实际会更难维护,更容易出现问题
代码量的多少不等于性能的快慢
xinyu391
2024-03-06 09:55:19 +08:00
@vczyh 他这里 common 相当于一个 Component 的集合,相当于一个 List 容器。
我倒是觉得 重构后的结构倒是可以的。
zzfly256
2024-03-06 10:03:09 +08:00
感觉不如之前的直观,心智负担稍微增加;同建议用 Wire 类的工具
BeautifulSoap
2024-03-06 10:08:22 +08:00
用 wire 或 dig 这种 di 库
pkoukk
2024-03-06 10:13:21 +08:00
同上,不建议做这种改造,可以用 DI 工具
fregie
2024-03-06 10:32:49 +08:00
这光看代码结构没有意义啊,要看这些 struct 实际的含义,是在业务上否能抽象出一个共同的概念出来,如果是完全不一样的东西只是长得像,还非要合并就是画蛇添足
mightybruce
2024-03-06 11:31:41 +08:00
你这个设计 完全可以考虑使用 DI,从目前的代码上看,这种重构并没有什么好转,关键看业务逻辑和非业务逻辑有没有分开。
NewA NewB 这种写法说实话很差, 考虑一下 builder 模式 和 option 模式吧。
vczyh
2024-03-06 12:34:24 +08:00
@xinyu391
每个结构引入了一些不需要的东西

看怎么理解了
dacapoday
2024-03-06 12:52:12 +08:00
画蛇添足
dacapoday
2024-03-06 12:57:48 +08:00
面向业务的项目,不要有任何的 common, util, core, helper, global config 。逻辑相似不代表可以复用,过多使用宽泛的命名和结构只会导致耦合。
gitrebase
2024-03-06 13:42:48 +08:00
@dacapoday #18 赞同,尤其是所谓的 common 和 global config ,在未来一定会被骂的
sampeng
2024-03-06 18:49:07 +08:00
你是反着来重构的,我上一版代码就是你想弄个 Common 的模式,我叫 GlobalService 。后来仔细琢磨了一下,这玩意就是写时一时爽,维护火葬场。一般项目维护时间是要大于写代码时间的。写代码稍微啰嗦点其实也没啥。所以用 wire 来解决写 New 的啰嗦问题。然后代码就清晰很多了。明确知道依赖是怎么进来的,怎么初始化的。

只有一些像 db 啊之类中间件的句柄我就直接整了个 GlobalComponent 。这种我个人仔细思考了是无所谓的。中间件这东西选好了基本就不会动,最多动选型。依赖的是接口。后续也好调整。
houshuu
2024-03-07 01:06:23 +08:00
虽然写 Go 不太做 DI ,但这情况倒是明显是挺适合的,我们组一直用的 https://github.com/uber-go/dig
Nazz
2024-03-07 08:40:50 +08:00
考虑下全局变量?

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

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

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

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

© 2021 V2EX