使用子包构建 go 接口

Structuring go interfaces with subpackages

我正在开发我的第一个真正的 go 应用程序,我正在努力了解我的代码文件应该是结构化的。

我的代码的主要部分是一些类型,它们都实现了一个公共接口。


type Runner interface {
  Run() string
}

它们将被打包。由于接口实现的数量将非常大,我想将它们(语义上)拆分为几个子包。

runner/
  blue/
  red/

Runner 实现需要访问在我的应用程序中其他地方定义的几个其他接口(例如,CacheSecret)。这些目前在单独的包中定义和实现。我的计划是使用 Config 结构,它包含所有这些实用程序接口并将其传递给 Runner 实现。

我不确定如何最好地处理这些子包以及将 Config 和接口声明放在哪里。 我的直观方法是在 runner 包中同时定义 Config 结构和 Runner 接口,并且只从那里定义 return 一个 []Runner 集合,但是这个违反 this recommendation。 此外,所需的导入数量和 运行 进入被禁止的循环引用的危险让我感觉,我的解决方案违背了最佳实践。

有什么改进我的代码结构的建议吗? 添加一个包含我所有接口定义和 Config 结构的 common 包是否可取?

我最终创建了一个包含接口和 Config 定义的 domain 包。

所以在domain/domain.go我有

package domain


type Config struct {
    Cache
}

type Runner interface {
  Run() string
}

type Cache interface {
  // ...
}

如上所述,runners 是在子包中构建的。我不导出类型,而是在每个包中都有一个函数收集所有类型并将它们作为接口返回。

runner/blue/blue.go:

package blue

import "my/domain"

func All(config domain.Config) (list []domain.Runner) {
    list = append(list, fooRunner{Config: config})
    list = append(list, barRunner{Config: config})
    return
}

runner/runner.go:

package runner

import ( 
  "my/runner/blue"
  "my/runner/red"
  "my/runner/domain"
)

func All(config domain.Config) (list []domain.Runner) {
    list = append(list, blue.All(config)...)
    list = append(list, red.All(config)...)
    return
}