Лучшая практика для разрешения циклической зависимости в Go - PullRequest
0 голосов
/ 03 марта 2019

У меня есть проект Go, который содержит оба этих пакета:

  • logging
    Imports config, поскольку я хочу отправить текущую конфигурацию в мою систему отчетов об ошибках
  • config
    Импортирует logging, потому что я хочу войти, если программе не удается открыть файлы конфигурации

Каков наилучший способ устранения этой ошибки зависимости?

1 Ответ

0 голосов
/ 03 марта 2019

В каком формате вы отправляете конфигурацию в систему сообщений об ошибках?Может быть, передать это для регистрации?Скажем, если это 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) {
    // ...
}

Таким образом, в этом случае вы можете объявить интерфейс в пакете конфигурации, который соответствует поведению, необходимому для ведения журнала.

/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)
}

И, наконец, третий пакет makeвсе это работает вместе.

/myapp

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

func init() {
    config.SetLogging(logging.Logging{})
}
...