抽象分支

2014年1月7日

“抽象分支”是一种技术[1],用于对软件系统进行大规模更改,这种方式允许您在更改仍在进行中时定期发布系统。

我们从软件系统的各个部分依赖于我们希望替换的模块、库或框架的情况开始

我们创建一个抽象层,用于捕获客户端代码的一部分与当前供应商之间的交互。我们更改客户端代码的该部分,使其完全通过此抽象层调用供应商。

我们逐渐将所有客户端代码迁移到使用抽象层,直到所有与供应商的交互都由抽象层完成。在此过程中,我们借此机会通过此抽象层改进供应商的单元测试覆盖率。

我们构建了一个新的供应商,它使用相同的抽象层[2]实现客户端代码的一部分所需的功能。准备就绪后,我们将切换客户端代码的该部分以使用新的供应商。

我们逐渐替换掉有缺陷的供应商,直到所有客户端代码都使用新的供应商。一旦不再需要有缺陷的供应商,我们就可以将其删除。一旦我们不再需要抽象层进行迁移,我们也可以选择将其删除。

我上面的描述描述了一个常见的情况,但可能会出现很多变化。有时您不能只为某些客户端更换供应商,您必须一次性完成所有更换。有时,您可以将供应商的功能分解为不同的子组件,并一次对一个子组件执行整个过程。

尽管存在这些变化,但有一个共同的主题。使用抽象层允许多个实现共存于软件系统中。使用一个抽象和多个实现的概念来执行从一个实现到另一个实现的迁移。确保系统始终构建和运行正常,以便您可以在进行替换时继续使用持续交付。尽可能多地寻找逐步进行更改的方法。

延伸阅读

Jez Humble 描述了他的团队如何使用抽象分支来替换 Thoughtworks 的持续交付工具“Go”的对象关系映射框架(ibatis 到 hibernate)和 Web UI 框架(velocity/JsTemplate 到 Ruby on Rails)。

Paul Hammant 提供了更多细节,介绍如何使用抽象分支,特别是作为版本控制分支的替代方案。

Steve Smith 描述了一种变体,该变体涉及验证两个实现是否对请求返回相同的结果。

致谢

感谢 Paul Hammant 提供的详细建议,以及作为重要的主要信息来源。

备注

1: 这种技术已经存在很长时间了,尽管它从未有一个流行的名字。Paul Hammant 在主张基于主干的开发时引入了“抽象分支”一词(他认为 Stacy Curl 最初提出了这个词)。这个名字似乎已经流行起来,现在是我最常听到的术语。

2: 在构建新功能时,我们可以使用功能标志在测试环境中运行新的供应商,并将其行为与有缺陷的供应商进行比较。