解决Go中循环依赖的最佳实践

问题描述 投票:1回答:1

我有一个包含这两个包的Go项目:

  • logging 导入config,因为我想将当前配置发送到我的错误报告系统
  • config 导入logging,因为如果程序无法打开配置文件我想记录

解决此依赖性错误的最佳做法是什么?

go circular-dependency
1个回答
1
投票

您将配置发送到错误报告系统的格式是什么?也许把它传递给伐木?比方说,如果它是json,那么在给它进行记录之前编组配置然后只记录[]byte结果。

但一般来说,如果两个软件包直接相互依赖,那么你可以做其中一个声明一个与另一个行为匹配的接口,然后让一个单独的软件包将具体实例作为接口传递。

例如:

/myapp/config

import "myapp/logging"

type Config struct {
     // ...
}

func NewConfig() *Config {
    // ...
    if err != nil {
        logging.LogError(err)
    }
}

/myapp/logging

import "myapp/config"

func LogConfig(c *config.Config) {
    // ...
}

func LogError(err error) {
    // ...
}

因此,在这种情况下,您可以在config包中声明一个与日志记录所需的行为相匹配的接口。

/myapp/config

type Logging interface {
    LogError(error)
}

var logging Logging

func SetLogging(l Logging) {
    logging = l
}

type Config struct {
     // ...
}

func NewConfig() *Config {
    // ...
    if err != nil {
        logging.LogError(err)
    }
}

然后通过简单地委托给原始函数,在日志包中实现一个类型实现该接口。

/myapp/logging

import "myapp/config"

func LogConfig(c *config.Config) {
    // ...
}

func LogError(err error) {
    // ...
}

type Logging struct{}

func (Logging) LogError(err error) {
    LogError(err)
}

最后有第三个包,让它们一起工作。

/myapp

import "myapp/config"
import "myapp/logging"

func init() {
    config.SetLogging(logging.Logging{})
}
© www.soinside.com 2019 - 2024. All rights reserved.