V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yujianwjj
V2EX  ›  Go 编程语言

一次 GO 项目重构的疑问

  •  
  •   yujianwjj · 257 天前 · 3349 次点击
    这是一个创建于 257 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 就好了。 但是,这样每个结构体其实引入了一些自己不需要的东西,我自己感觉不是特别好。

    各位大佬怎么看?

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

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

    只有一些像 db 啊之类中间件的句柄我就直接整了个 GlobalComponent 。这种我个人仔细思考了是无所谓的。中间件这东西选好了基本就不会动,最多动选型。依赖的是接口。后续也好调整。
    houshuu
        19
    houshuu  
       256 天前
    虽然写 Go 不太做 DI ,但这情况倒是明显是挺适合的,我们组一直用的 https://github.com/uber-go/dig
    Nazz
        20
    Nazz  
       256 天前 via Android
    考虑下全局变量?
    xhd2015
        21
    xhd2015  
       232 天前 via iPhone
    在 Go 中使用 New 无非就是想预留一些注入点,为将来写单测留出可能。但是基于这种方式的代码冗余度大大增加。我的建议是直接依赖包级别的函数和变量。
    单测部分,使用 https://github.com/xhd2015/xgo 来做无侵入的测试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1929 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 16:23 · PVG 00:23 · LAX 08:23 · JFK 11:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.