在没有循环依赖关系的情况下在Go中注册软件包
我有一个中央包,提供其他包依赖的几个接口(让我们调用一个客户端).那些其他包,提供了这些第一个接口(UDPClient,TCPClient)的几个实现.我通过调用中央程序包中的NewClient实例化客户端,并从其中一个依赖程序包中选择并调用适当的客户机实现.
当我想告诉中间包关于这些其他软件包时,这一切分崩离析,所以它知道它可以创建什么客户端.这些依赖客户端实现也导入中央包,创建Go不允许的循环依赖. 最好的方法是什么?我不想在一个包中将所有这些实现进行混合,并且创建一个单独的注册表包看起来是过度的.目前,我有每个实现注册本身与中央包,但是这需要用户知道导入使用客户端的每个单独的二进制文件中的每个实现. import ( _ udpclient _ tcpclient client )
标准库以多种方式解决了这个问题:
1)没有“中央”登记处 这个例子就是不同的散列算法. 当你需要一个“哈希尔”时,你明确地说出你想要的那个,并实例化一个. h1 := md5.New() h2 := sha256.New() 这是最简单的解决方案,它也提供了良好的分离:哈希包不必知道或担心实现. 如果您知道或者您可以决定先前需要哪个实现,这是首选解决方案. 2)与“中央”登记处 这基本上是你提出的解决方案.实现必须以某种方式注册(通常是在一个包init()函数中). 一个例子是 该图像包具有 在这种情况下,如果我们想要图像解码机制是可扩展的,则注册是不可避免的.最简单的做法是在包init()函数中,通过在导入时指定包名称的空白标识符来触发. 请注意,此解决方案还提供了使用特定实现来解码图像的可能性,具体实现还提供了Decode()函数,例如 那么最好的方法? 取决于您的要求.如果你知道或者你可以决定你需要哪个实现,那么你可以去#1.如果您无法决定或不知道您需要可扩展性,请与#2进行交流. …或下面提到#3. 3)提出第三个解决方案:“自定义”注册表 您仍然可以方便地使用“中央”注册表,其界面和实现与“自动扩展性”的费用分开. 这个想法是,你有包pi的接口.你有包pa,pb等的实现 并且您创建一个将要使用“工厂”方法的包pf,例如pf.NewClient(). pf包可以引用包pa,pb,pi,而不创建循环依赖. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |