当前位置: 首页 > 面试题库 >

在Go中注册程序包而无需循环依赖

萧飞
2023-03-14
问题内容

我有一个中央程序包,它提供了其他程序包所依赖的几个接口(我们称其为Client)。这些其他的包,提供的第一类接口的几种实现(UDPClientTCPClient)。我Client通过调用NewClient中央程序包实例化一个,它从一个相关程序包中选择并调用适当的客户端实现。

当我想将其他软件包告诉中央软件包时,这变得很困难,因此它知道可以创建哪些客户端。这些从属客户端实现还导入中央程序包,从而创建Go不允许的循环依赖项。

最好的前进方向是什么?我不希望将所有这些实现混在一起放在一个程序包中,而创建一个单独的注册表程序包似乎有些过头了。目前,每个实现都在中央程序包中进行注册,但这需要用户知道如何在每个使用客户端的二进制文件中导入每个实现。

import (
    _ udpclient
    _ tcpclient
    client
)

问题答案:

标准库通过多种方式解决了此问题:

1)没有“中央”注册表

这样的示例是不同的哈希算法。该crypto包仅定义Hash接口(类型及其方法)。具体实现在不同的封装(其实子文件夹,但并不需要如此),例如crypto/md5crypto/sha256

当您需要“哈希器”时,您可以明确说明您要的实例并实例化该实例,例如

h1 := md5.New()
h2 := sha256.New()

这是最简单的解决方案,并且还可以为您提供良好的分离:hash程序包不必了解或担心实现。

如果您知道或可以先决定要使用哪种实现,则这是首选的解决方案。

2)具有“中央”注册表

这基本上是您建议的解决方案。实现必须以某种方式注册自己(通常在包init()函数中)。

image包装就是一个例子。该软件包定义了Image接口及其一些实现。在image/gifimage/jpeg和等不同的程序包中定义了不同的图像html" target="_blank">格式image/png

所述image封装具有Decode()其解码并返回一个函数Image从指定io.Reader。通常不知道哪种类型的图像来自阅读器,因此您不能使用特定图像格式的解码器算法。

在这种情况下,如果我们希望图像解码机制是可扩展的,那么注册是不可避免的。最干净的方法是在包init()函数中,该函数通过在导入时为包名指定空白标识符来触发。

请注意,此解决方案还使您可以使用特定的实现对图像进行解码Decode(),例如,具体的实现也提供了功能png.Decode()

那么最好的方法呢?

取决于您的要求。如果您知道或可以决定所需的实现,请选择#1。如果您不确定还是不知道并且需要可扩展性,请选择#2。

…或者继续下面列出的#3。

3)提出第三个解决方案:“自定义”注册表

您仍然可以方便地将“中央”注册表与界面和实现分开,而以“自动扩展性”为代价。

这个想法是你在package中有接口pi。你必须在包的实现papb等等。

然后,您将创建一个pf具有所需“工厂”方法的程序包,例如pf.NewClient()。该pf包可以指包papbpi而不创建循环依赖关系。



 类似资料:
  • 问题内容: 我有以下两项艰巨的任务 用于获取计算机(Linux)中的接口列表并获取每个接口的总线地址。我在同一本剧本中还有另外一项任务,如下 我希望对var2的值进行迭代,然后打印总线号。 var2.results如下 我的目标是获取上述每个项目中stdout的值,例如(“ stdout”:“ 09:00.0”)。我试图给像 但这不能正确提供标准输出中的总线值。当第二个变量是and indexed

  • 小程序 App App(Object) App() 函数用来注册一个小程序。接受一个 Object 参数, App() 必须在 app.js 中调用,且只能调用一次。 Object参数说明: 属性 类型 描述 触发时机 onLaunch Function 生命周期回调—监听小程序初始化 小程序初始化完成时触发(全局只触发一次) onShow Function 生命周期回调—监听小程序显示 小程序启

  • 这个程序应该从用户那里读取2个多项式,然后打印出求和;一旦两个多项式都被输入,就会陷入无限循环。 > 为了存储一个多项式,使用了一个带有指向下一项(节点)的*plink前向声明的结构 每个多项式都有一个头节点,它有助于以循环方式遍历列表。 因为头节点不包含任何与多项式“相关”的数据,所以它们的指数字段被初始化为-1

  • 我正在编写一个基于文本的冒险游戏,我遇到了一个问题。我正在将它从终端移植到JFrame GUI,我需要它在继续之前等待用户输入。我设置了一个系统,其中有一个名为按钮的布尔变量,它开始时为false。当按下提交文本按钮时,它会将其更改为true。有一个while循环,它会等待按钮变为true,然后才允许程序继续,基本上是暂停程序直到用户提交输入。问题是,只有当我在while循环中写入system.o

  • 问题内容: 我正在为重定向脚本编写基准测试。 我希望程序查询某些重定向到AppStore的URL。但是我不希望下载AppStore页面。我只想记录重定向URL或错误。 我该如何告诉转到查询URL而无需第二次重定向查询? 更新 这两个答案都是正确的,但是: 我尝试了两种解决方案。我正在做基准测试。我使用10-500个go例程运行1个或多个go进程。他们循环查询URL。我的服务器也是用go编写的。它每

  • 问题内容: 我有两个文件和,分别定义了两个类和。 直到今天,用于引用该对象的定义,因此我已经做了 在文件中。 但是,到目前为止,我已经为引用该对象的对象创建了一个新方法。 尝试导入时遇到了问题:我尝试了一下,当程序运行并调用了using的方法时,出现了一个未定义的异常。 我该怎么办? 问题答案: 导入Python模块 是一篇很棒的文章,介绍了Python中的循环导入。 解决此问题的最简单方法是将路