Golang Go语言项目重构的疑问
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 就好了。 但是,这样每个结构体其实引入了一些自己不需要的东西,我自己感觉不是特别好。
各位大佬怎么看?
Golang Go语言项目重构的疑问
更多关于Golang Go语言项目重构的疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
别 func New 了,go 里直接就能 newA := A{a,b,c}
更多关于Golang Go语言项目重构的疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
用 wire 或者 fx 做依赖注入
struct 你要有实际意义,common 这种模糊的东西最好去掉,看似提出公共东西了,但是一点也不好维护,不同的东西就是应该分成多个 struct ,要是你觉得一样那就重新思考到底是不是不同的东西,如果是那就分开好了,成员变量相似又不是相同。
你没想过变量的可访问性?
感觉还不如之前的,你要是嫌麻烦可以用 Wire 这样的 DI 工具。
从写代码的角度,我肯定更喜欢一个 Common 搞定。
以及更激进些,ComponentA ComponentB ComponentC ComponentD 是否能合并成 Component 呢😁
习惯开发弱类型语言脚本语言的老毛病了
现在这种重构之后实际会更难维护,更容易出现问题
代码量的多少不等于性能的快慢
他这里 common 相当于一个 Component 的集合,相当于一个 List 容器。
我倒是觉得 重构后的结构倒是可以的。
用 wire 或 dig 这种 di 库
同上,不建议做这种改造,可以用 DI 工具
这光看代码结构没有意义啊,要看这些 struct 实际的含义,是在业务上否能抽象出一个共同的概念出来,如果是完全不一样的东西只是长得像,还非要合并就是画蛇添足
你这个设计 完全可以考虑使用 DI,从目前的代码上看,这种重构并没有什么好转,关键看业务逻辑和非业务逻辑有没有分开。
NewA NewB 这种写法说实话很差, 考虑一下 builder 模式 和 option 模式吧。
每个结构引入了一些不需要的东西
看怎么理解了
画蛇添足
面向业务的项目,不要有任何的 common, util, core, helper, global config 。逻辑相似不代表可以复用,过多使用宽泛的命名和结构只会导致耦合。
#18 赞同,尤其是所谓的 common 和 global config ,在未来一定会被骂的
你是反着来重构的,我上一版代码就是你想弄个 Common 的模式,我叫 GlobalService 。后来仔细琢磨了一下,这玩意就是写时一时爽,维护火葬场。一般项目维护时间是要大于写代码时间的。写代码稍微啰嗦点其实也没啥。所以用 wire 来解决写 New 的啰嗦问题。然后代码就清晰很多了。明确知道依赖是怎么进来的,怎么初始化的。
只有一些像 db 啊之类中间件的句柄我就直接整了个 GlobalComponent 。这种我个人仔细思考了是无所谓的。中间件这东西选好了基本就不会动,最多动选型。依赖的是接口。后续也好调整。
虽然写 Go 不太做 DI ,但这情况倒是明显是挺适合的,我们组一直用的 https://github.com/uber-go/dig
考虑下全局变量?
在 Go 中使用 New 无非就是想预留一些注入点,为将来写单测留出可能。但是基于这种方式的代码冗余度大大增加。我的建议是直接依赖包级别的函数和变量。
单测部分,使用 https://github.com/xhd2015/xgo 来做无侵入的测试
针对您提出的Golang Go语言项目重构的疑问,以下是一些专业建议:
- 提取重复代码:检查项目中是否存在重复的代码块,将其提取到单独的函数或模块中,以提高代码的可读性和可维护性。
- 利用函数作为一等公民:Go语言中,函数可以作为变量传递、赋值和返回,这有助于将复杂的逻辑拆分成更小、更易于管理的部分。
- 封装逻辑到结构体和接口:通过封装相关的数据和函数到一个结构体中,可以使代码更加模块化。同时,使用接口可以抽象出通用的行为,便于代码之间的解耦和替换。
- 遵循SOLID原则:SOLID原则(单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则)是面向对象编程中重要的设计原则,同样适用于Go语言。遵循这些原则可以使代码更加健壮和易于维护。
- 使用Go Modules管理依赖:对于依赖较多的项目,使用Go Modules可以轻松地管理项目的依赖关系,并保证依赖的版本一致性。
- 进行性能测试和优化:定期进行性能测试,使用性能分析工具(如pprof)来定位瓶颈,然后针对性地进行优化。
综上所述,Go语言项目重构是一个涉及多方面的工作,需要综合考虑代码结构、性能、依赖管理等多个方面。希望这些建议能对您有所帮助。