如何在不创建新包的情况下解决循环依赖?
How to solve circular dependency without creating new package?
在 golang 中想要一个带有全局注册表的插件系统。结构可以简化如下:
/plugins/registry.go
/plugins/plugin1/impl.go
registry.go:
package plugins
import "plugins/plugin1" // required for plugin1.MakePlugin
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry = []Factory{
plugin1.MakePlugin,
}
impl.go:
package plugin1
import "plugins" // required for IPlugin
type Plugin struct {
x int
}
func MakePlugin(x int) plugins.IPlugin {
return &Plugin{
x: x,
}
}
如何在不移动 IPlugin
到第 3 个(例如 common
)包的情况下解决?
PS。我想如果我 return *Plugin
来自 MakePlugin
这将与 Factory 兼容,但它不兼容!!!
“如何在不将 IPlugin
移动到第 3 个(例如 common
)包的情况下解决?”
您至少有两个选择:
- 将注册移动到第三个(例如
main
)包。
- 让每个插件在被其他包导入时自行注册。
示例 #1
package plugins
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry []Factory
func Register(ff ...Factory) {
registry = append(registry, ff...)
}
package main
import (
"plugins"
"plugins/plugin1"
)
func init() {
plugins.Register(plugin1. MakePlugin)
}
func main() {
// ...
}
示例 #2
package plugins
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry []Factory
func Register(ff ...Factory) {
registry = append(registry, ff...)
}
package plugin1
import "plugins" // required for IPlugin
func init() {
plugins.Register(MakePlugin)
}
type Plugin struct {
x int
}
func MakePlugin(x int) plugins.IPlugin {
return &Plugin{
x: x,
}
}
package main
import (
"plugins"
_ "plugins/plugin1" // will execute init() i.e. register
)
func main() {
// ...
}
尝试将接口从它们的实现分离到抽象的外部包。然后,根据 Dependency injection and Adapter pattern 范式依赖它们。
在 golang 中想要一个带有全局注册表的插件系统。结构可以简化如下:
/plugins/registry.go
/plugins/plugin1/impl.go
registry.go:
package plugins
import "plugins/plugin1" // required for plugin1.MakePlugin
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry = []Factory{
plugin1.MakePlugin,
}
impl.go:
package plugin1
import "plugins" // required for IPlugin
type Plugin struct {
x int
}
func MakePlugin(x int) plugins.IPlugin {
return &Plugin{
x: x,
}
}
如何在不移动 IPlugin
到第 3 个(例如 common
)包的情况下解决?
PS。我想如果我 return *Plugin
来自 MakePlugin
这将与 Factory 兼容,但它不兼容!!!
“如何在不将 IPlugin
移动到第 3 个(例如 common
)包的情况下解决?”
您至少有两个选择:
- 将注册移动到第三个(例如
main
)包。 - 让每个插件在被其他包导入时自行注册。
示例 #1
package plugins
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry []Factory
func Register(ff ...Factory) {
registry = append(registry, ff...)
}
package main
import (
"plugins"
"plugins/plugin1"
)
func init() {
plugins.Register(plugin1. MakePlugin)
}
func main() {
// ...
}
示例 #2
package plugins
type IPlugin interface {
Register() error
}
type Factory func(x int) IPlugin
var registry []Factory
func Register(ff ...Factory) {
registry = append(registry, ff...)
}
package plugin1
import "plugins" // required for IPlugin
func init() {
plugins.Register(MakePlugin)
}
type Plugin struct {
x int
}
func MakePlugin(x int) plugins.IPlugin {
return &Plugin{
x: x,
}
}
package main
import (
"plugins"
_ "plugins/plugin1" // will execute init() i.e. register
)
func main() {
// ...
}
尝试将接口从它们的实现分离到抽象的外部包。然后,根据 Dependency injection and Adapter pattern 范式依赖它们。