合并两个Python API而不破坏兼容性

时间:2016-11-08 00:34:43

标签: python api-design

以下是该场景:

存储系统A(Java)是默认设置,并具有Python API API_A。最近引入了存储系统B(Java / C ++),但没有Python API。人们"某种程度上" BAPI_A合作,但速度非常慢,特别是随着规模的增加。因为,这是Python API的唯一选择,现在很多代码依赖于API_AB进行交互。

来自存储系统B的团队现在拥有一个Python API API_BAPI_B显然更有效率。但是,API_AAPI_B之间存在很多差异。例如,list目录方法返回具有完全不同字段的对象。 API_B不允许对目录进行递归删除,但API_A会这样做。等等...

问题:

在不破坏兼容性的情况下合并两个API的最佳方法是什么?特别是,由于API_A已被使用,将API_B透明地集成到其中的最佳方式是什么?

我不认为创建装饰器会起作用,因为API之间的方法签名会有所不同。 API_A中的某些方法API_B中没有。 (提升NotImplementedException是这里唯一的选择。)

我能想到的唯一解决方案是天真的解决方案,我必须在API_A中检查每个函数:

if self.isStorageA:
    return method_of_A(args)
else:
    return method_of_B(args, args)

我正在寻找一种更好,更易于维护的方法。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

为API B编写一个包装器库,"看起来像" API A

特别是,它必须提供具有完全相同签名的完全相同的方法。如果API B没有实现某些功能(如递归枚举),则包装器必须根据API B重新实现此功能。例如,您可以编写一个枚举当前目录的函数,然后是每个子目录,依此类推。 ,以替换API A的本机功能。如果无法执行此操作(即,如果存在API A提供的某些功能以及根本无法使用API​​ B执行的功能),则API B不适用替换API A,您不应该继续执行您的计划。

您还应该为包装器编写一系列单元测试,以确保其行为与API A在各种条件下的行为相同,特别是包括边缘情况。如果A已经有单元测试,那么就使用它们。

最后,一旦你确定包装器与A无法区分,你就可以用包装器替换A.只需更换模块和软件包就足够简单了,但如果由于某种原因这对您不起作用,您可以替换sys.modules中的A以确保导入A获取包装器。