在Go语言中处理解耦的最佳方法是在两个不同的包中使用相似的结构,但结构中的子项使它变得困难?

hi3rlvi2  于 2023-06-19  发布在  Go
关注(0)|答案(1)|浏览(117)

我是一个相对较新的人,一直在做大量的重写,试图尽可能地减少我的依赖图。我很高兴我得到了它,但有一个部分,我不知道如何最好地处理。如果答案是,“你将在两者之间建立依赖关系”,那也很好,我只是在寻找一个好的方法,而不是期待奇迹。
所以下面我有两个包,ab,它们都有相同的结构。通常你可以在main中将一个转换成另一个,但是每个都有一个子项,它也是一个结构体,这阻止了Go允许它,即使子项具有相同的签名。
一种方法是在B中的结构中引用A.TzConfig,让它有一个依赖项,但这正是我试图摆脱的。
我想另一种方法是创建一个接口,然后通过方法获取Loc的值,我认为这会起作用,但我还没有尝试过,因为这意味着为只是数据结构的东西创建方法(实际结构有很多项,为了简单起见,我在这里将其简化为基本内容),这似乎有点矫枉过正。
我可以把TzConfig移到第三个模块中,这样它们就可以同时引用这个模块,而不是一个模块引用另一个模块,这就是我所想到的。
所以我的问题是,从一个真实的有经验的人来说,在围棋中处理这种情况的最好方法是什么?
我应该提到的是,它们有重复的结构体的原因只是因为我试图打破它们之间的依赖关系,原始代码只是在一个包中有结构体,另一个包引用它。

package a

type Cfg struct {
    Addr                 string
    Loc                  TzConfig
}

type TzConfig struct {
    String string
    TZ     *time.Location `validate:"noDescent"`
}

func GetCfg() Cfg {
    t, _ := time.LoadLocation(`MST`)
    return Cfg{
        Addr: "abc",
        Host: "a.bc.d",
        Loc:  config.TzConfig{
            String: "MST",
            TZ:     t,
        },
    }
}
package b

type Cfg struct {
    Addr                 string
    Loc                  TzConfig
}

type TzConfig struct {
    String string
    TZ     *time.Location `validate:"noDescent"`
}

func DoSomethingWithConfig(c Cfg) {
    fmt.Println(c)
}
package main

main() {
     c := a.GetCfg()
     d := b.DoSomethingWithConfig(b.Cg(c))
     fmt.Println(d)
}
fhg3lkii

fhg3lkii1#

恕我直言,@BurakSerdar提供的建议非常好,非常适合你的场景。我用这种方式重写了代码。

package common

package common

import "time"

type Cfg struct {
    Addr string
    Loc  TzConfig
}

type TzConfig struct {
    String string
    TZ     *time.Location `validate:"noDescent"`
}

在这里,您应该放置常见的结构体、函数、方法等。

package a

package a

import (
    "dependencies/common"
    "time"
)

type Cfg struct {
    common.Cfg
    Host string
}

func GetCfg() Cfg {
    t, _ := time.LoadLocation(`MST`)
    return Cfg{
        Cfg: common.Cfg{
            Addr: "abc",
            Loc: common.TzConfig{
                String: "MST",
                TZ:     t,
            },
        },
        Host: "a.bc.d",
    }
}

在这里,您可以看到与a包相关的特定代码,它继承了common包的共享代码,如您在import部分中所看到的。
请注意,我使用了结构体嵌入特性来获取common包中定义的共享字段。

package b

package b

import (
    "dependencies/common"
    "fmt"
)

func DoSomethingWithConfig(c common.Cfg) string {
    return fmt.Sprint(c)
}

在这里,没有什么特别要提的。

package main

package main

import (
    "dependencies/a"
    "dependencies/b"
    "fmt"
)

func main() {
    c := a.GetCfg()
    d := b.DoSomethingWithConfig(c.Cfg)
    fmt.Println(d)
}

在这里,代码应该非常简单。我导入了ab软件包来利用它们的功能。
再次,我想明确的是,这是一个主观的主题,因此没有银弹解决方案。对我来说,看起来整洁而清晰。我肯定会选择这种方式。让我知道,谢谢!

相关问题