I am developing my first real go application and am trying to wrap my hand around my codefiles should be structured.
The main part of my code is going to be a number of types which all implement a common interface.
type Runner interface {
Run() string
}
They are going to be in a package. As the number of the interface implementations is going to be very large I would like to split them (semantically) into a couple of subpackages.
runner/
blue/
red/
The Runner
implementation need access to a couple of other interfaces that are defined elsewhere in my application (e.g., Cache
and Secret
). Those are currently defined & implemented in separate packages. My plan is to use a Config
struct, which contains all those utility interfaces and pass it to the Runner
implementations.
I am unsure how to best handle those subpackages and where to put the Config
and interface declarations.
My intuitive approach would be to define both the Config
struct and the Runner
interface in the runner
package and only return a []Runner
collection from there, but this violates this recommendation.
Also, the number of imports required and the danger of running into circular references which are prohibited gives me the feeling, that my solution is going against best practices.
Are there any suggestions how to improve my code structure?
Would adding a common
package which contains all my interface definitions and the Config
struct be advisable?
CodePudding user response:
I ended up creating a domain
package containing the interface and Config
definintions.
So in domain/domain.go
I have
package domain
type Config struct {
Cache
}
type Runner interface {
Run() string
}
type Cache interface {
// ...
}
The runners are structured in subpackages as mentioned above. I do not export the types but rather have a function in each package collecting all of them and returning it them as interfaces.
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
}