首页 >后端开发 >Golang >如何在不创建循环依赖的情况下注册Go包?

如何在不创建循环依赖的情况下注册Go包?

DDD
DDD原创
2024-12-21 06:52:10796浏览

How to Register Go Packages Without Creating Cyclic Dependencies?

在没有循环依赖的情况下在 Go 中注册包

问题:

你有一个提供接口并依赖于的中央包提供这些接口的实现的其他包。然而,在中央包中包含这些依赖包会产生循环依赖,这是 Go 不允许的。

标准库解决方案:

  • 不带中央注册表: 在一个包中定义接口,在单独的包中定义具体实现。用户明确指定要使用的实现。
  • 使用中央注册表: 实现在中央注册表中注册自己(通常通过包 init() 函数)。这允许扩展性,但需要手动注册。

自定义注册表解决方案:

  • 创建提供“工厂”方法的附加包(pf)实例化具体的实现。
  • 工厂包依赖于接口包(pi)和实现包(pa, pb 等),但这不会创建循环,因为 pf 不依赖于自身。

选择最佳解决方案:

理想方法取决于具体要求:

  • 如果您可以预先确定要使用的实现,请选择第一个解决方案(没有中央注册表)。
  • 如果可扩展性至关重要并且您无法预测实现,请考虑第二个或第三个解决方案(使用中央或自定义注册表)。

代码示例对于自定义注册表解决方案:

// Package pi defines an interface I.
package pi

type I interface {
    // Some method.
    DoSomething()
}

// Package pa implements I with type A.
package pa

import "pi"

type A struct{}

func (a *A) DoSomething() {
    // Some implementation.
}

// Package pb implements I with type B.
package pb

import "pi"

type B struct{}

func (b *B) DoSomething() {
    // Some implementation.
}

// Package pf provides a factory to create instances of I.
package pf

import (
    "pi"
    "pa"
    "pb"
)

// NewClient returns an instance of I based on a flag.
func NewClient(flag string) pi.I {
    switch flag {
    case "a":
        return &pa.A{}
    case "b":
        return &pb.B{}
    default:
        panic("Invalid flag")
    }
}

以上是如何在不创建循环依赖的情况下注册Go包?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn