我正在开发我的第一个真正的go应用程序,我试图把我的手围绕我的代码文件应该结构化。
我的代码的主要部分将是一些类型,它们都实现了一个公共接口。
type Runner interface {
Run() string
}
他们将在一个包里。由于接口实现的数量将会非常大,我想把它们(语义上)分成几个子包。
runner/
blue/
red/
Runner
实现需要访问在我的应用程序中其他地方定义的几个其他接口(例如,Cache
和Secret
)。它们是当前定义的&在单独的包中实现。我的计划是使用Config
结构,它包含所有这些实用程序接口并将其传递给Runner
实现。
我不确定如何最好地处理这些子包,以及在哪里放置Config
和接口声明。我的直觉方法是在runner
包中定义Config
结构体和Runner
接口,并从那里只返回[]Runner
集合,但这违反了本建议。此外,所需导入的数量和遇到禁止循环引用的危险使我觉得,我的解决方案违背了最佳实践。
有什么建议如何改善我的代码结构?添加包含所有接口定义和Config
结构的common
包是否可取?
我最终创建了一个包含接口和Config
定义的domain
包。
在domain/domain.go
中输入
package domain
type Config struct {
Cache
}
type Runner interface {
Run() string
}
type Cache interface {
// ...
}
运行程序在子包中结构化,如上所述。我不导出类型,而是在每个包中使用一个函数收集所有类型,并将它们作为接口返回。
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
}