向库添加新的依赖项,并进行兼容的 API 更改会影响二进制兼容性吗?
Does adding a new dependency to a library, with compatible API changes, affect binary compatibility?
我的问题:
只要库的外部 API 向后兼容,向库添加新的依赖项是否会影响二进制兼容性?
我的情况:
我的 CBOR library 包含 类 用于任意精度算术(在 PeterO 命名空间中)。 (它在 C# 和 Java 中;Java 版本在单独的存储库中,但同样的问题适用于两个版本。)
我已经将这些 类 移动到一个新的命名空间(在 PeterO.Numbers 中),并重命名它们(保留原来的 类 以便向后兼容),因为它们所在的命名空间now 意味着只包含实用程序 类。我计划将新的 类 移动到一个单独的库,并使 CBOR 库调用该库作为依赖项,因为任意精度 类 在 CBOR 之外显然很有用。 (我计划最终弃用旧的 类。)
但我担心以这种方式创建一个单独的库是否存在二进制兼容性问题,以至于我不能只更新次要版本,还要更新主要版本。在撰写本文时,CBOR 库的版本为 2.3.1。我可以这样做并将版本更改为 2.4 还是仅 3.0?
我将回答 Java 版本。 This section of the Java Language Specification 详细描述了在保持二进制兼容性的同时可以对应用程序进行的更改。
据我了解,您的更改(尽管它们可能会影响很大一部分源代码)是简单的重构,将一些实用程序 classes 暴露给另一个模块,re-direct 旧的 classes 来调用这个新模块。 Evolution of Packages:
部分对此进行了描述
A new top level class or interface type may be added to a package without breaking compatibility with pre-existing binaries, provided the new type does not reuse a name previously given to an unrelated type.
所以这不会破坏与使用您的库的现有 classes 的二进制兼容性。任何用于调用 CBORUtil.doArithmetic()
的现有 class CBORClient
将继续工作而无需 re-compile 它,因为该方法仍然存在,只是它的主体已更改为调用另一个模块进行计算。
最好避免在下一个主要版本之前添加新的依赖项,在此之前,在内部添加更改并使用相同的 class 创建新的 arbitrary-precision 库并在没有依赖项的情况下同步它们。
因此对于 2.4 版,在新命名空间中添加更改并从旧 class 调用它们并为 arbitrary-precision classes 创建另一个 class 库并将它们同步到下一个CBOR 库的主要版本
只要您从一个界面开始,并且所有图书馆的客户都知道该界面,您就可以了。只要您的库具有其客户理解的接口并且它实现了该接口,您的代码驻留在您的库中或库外的任何位置都没有关系。
这是一个古老的问题,15 年前已由 COM(组件对象模型)解决。将您的接口与实现分开,您就是黄金。
我的问题:
只要库的外部 API 向后兼容,向库添加新的依赖项是否会影响二进制兼容性?
我的情况:
我的 CBOR library 包含 类 用于任意精度算术(在 PeterO 命名空间中)。 (它在 C# 和 Java 中;Java 版本在单独的存储库中,但同样的问题适用于两个版本。)
我已经将这些 类 移动到一个新的命名空间(在 PeterO.Numbers 中),并重命名它们(保留原来的 类 以便向后兼容),因为它们所在的命名空间now 意味着只包含实用程序 类。我计划将新的 类 移动到一个单独的库,并使 CBOR 库调用该库作为依赖项,因为任意精度 类 在 CBOR 之外显然很有用。 (我计划最终弃用旧的 类。)
但我担心以这种方式创建一个单独的库是否存在二进制兼容性问题,以至于我不能只更新次要版本,还要更新主要版本。在撰写本文时,CBOR 库的版本为 2.3.1。我可以这样做并将版本更改为 2.4 还是仅 3.0?
我将回答 Java 版本。 This section of the Java Language Specification 详细描述了在保持二进制兼容性的同时可以对应用程序进行的更改。
据我了解,您的更改(尽管它们可能会影响很大一部分源代码)是简单的重构,将一些实用程序 classes 暴露给另一个模块,re-direct 旧的 classes 来调用这个新模块。 Evolution of Packages:
部分对此进行了描述A new top level class or interface type may be added to a package without breaking compatibility with pre-existing binaries, provided the new type does not reuse a name previously given to an unrelated type.
所以这不会破坏与使用您的库的现有 classes 的二进制兼容性。任何用于调用 CBORUtil.doArithmetic()
的现有 class CBORClient
将继续工作而无需 re-compile 它,因为该方法仍然存在,只是它的主体已更改为调用另一个模块进行计算。
最好避免在下一个主要版本之前添加新的依赖项,在此之前,在内部添加更改并使用相同的 class 创建新的 arbitrary-precision 库并在没有依赖项的情况下同步它们。
因此对于 2.4 版,在新命名空间中添加更改并从旧 class 调用它们并为 arbitrary-precision classes 创建另一个 class 库并将它们同步到下一个CBOR 库的主要版本
只要您从一个界面开始,并且所有图书馆的客户都知道该界面,您就可以了。只要您的库具有其客户理解的接口并且它实现了该接口,您的代码驻留在您的库中或库外的任何位置都没有关系。
这是一个古老的问题,15 年前已由 COM(组件对象模型)解决。将您的接口与实现分开,您就是黄金。