向库添加新的依赖项以及兼容的 API 更改是否会影响二进制兼容性?

2022-09-02 04:32:09

我的问题:

向库添加新的依赖项是否会影响二进制兼容性,只要库的外部 API 在其他方面是向后兼容的?

我的情况:

我的 CBOR 库包含任意精度算术的类(在 PeterO 命名空间中)。(它是在C#和Java中;Java版本在一个单独的存储库中,但同样的问题适用于这两个版本。

我已将这些类移动到一个新的命名空间(在 PeterO.Numbers 中),并重命名了它们(保留原始类以实现向后兼容性),因为它们现在所在的命名空间只包含实用程序类。我计划将新类移动到一个单独的库中,并使 CBOR 库将该库作为依赖项调用,因为任意精度类在 CBOR 之外显然很有用。(我计划最终弃用旧类。

但是我担心以这种方式制作单独的库是否是一个二进制兼容性问题,这样我不仅不能更新次要版本,还可以更新主要版本。在撰写本文时,CBOR 库的版本为 2.3.1。我是否可以执行此操作并将版本更改为 2.4 或仅更改为 3.0?


答案 1

只要您从一个界面开始,并且所有库的客户端都知道该界面,您就会没事。代码驻留在库或库外库的库的哪个位置并不重要,只要您的库具有其客户端理解的接口并实现了该接口即可。

这是一个古老的问题,15年前由COM(组件对象模型)解决。将你的接口与实现分开,你就是黄金。


答案 2

我将回答Java版本。Java 语言规范的这一部分详细介绍了在保持二进制兼容性的同时可以对应用程序进行的更改。

据我所知,您的更改(尽管它们可能会影响源代码的很大一部分)是简单的重构,将一些实用程序类公开给另一个模块,并重新定向旧类以调用此新模块。这在软件包的演变一节中进行了描述:

可以将新的顶级类或接口类型添加到包中,而不会破坏与预先存在的二进制文件的兼容性,前提是新类型不重用以前为不相关类型指定的名称。

因此,这不会破坏与使用库的现有类的二进制兼容性。任何用于调用的现有类都将继续工作,而无需重新编译它,因为该方法仍然存在,只有其主体已更改为调用另一个模块进行计算。CBORClientCBORUtil.doArithmetic()


推荐