在 Go 中注册没有循环依赖的包
设计 Go 应用程序时,避免包之间的循环依赖至关重要,因为一个包依赖于一个包另一个又取决于第一个。在跨多个包定义接口及其实现时,可能会出现这种情况。
问题:
我们如何注册客户端实现而不在我们的中央包之间创建循环依赖关系(与客户端接口)和包含实现的包(例如,UDPClient, TCPClient)?
答案:
标准库提供了两种主要方法来解决这个问题:
1.没有中央注册表
在中央包中定义客户端接口。对于实现,在实例化客户端时显式指定所需的实现。例如:
import ( "hash/md5" "hash/sha256" ) func main() { h1 := md5.New() h2 := sha256.New() }
2。使用中央注册表
创建一个注册表机制,实现可以自行注册。这种方法类似于问题中讨论的自发注册。它用在图像包中,其中各种图像格式解码器(例如 GIF、JPEG、PNG)自行注册。
3.建议的自定义注册表
引入一个单独的工厂包,提供用于创建客户端的 NewClient() 方法。这个包可以引用接口包和实现包,而不会造成循环依赖。例如:
package pi // Client represents the client interface. type Client interface { ... }
package pa // UDPClient implements the Client interface. type UDPClient struct { ... }
package pb // TCPClient implements the Client interface. type TCPClient struct { ... }
package pf import ( "pi" "pa" "pb" ) // NewClient creates a client based on the implementation. func NewClient(impl string) pi.Client { switch impl { case "udp": return &pa.UDPClient{} case "tcp": return &pb.TCPClient{} default: panic("Unsupported implementation") } }
以上是如何在不创建循环依赖的情况下注册Go包实现?的详细内容。更多信息请关注PHP中文网其他相关文章!