首页/开发/系统分析与架构设计速查/抽象分支(Branch By Abstraction)
架构风格与模式58 条

抽象分支(Branch By Abstraction)

在同一代码库中引入抽象层,把旧实现替换为抽象调用,再并行开发新实现并切换,最后清理抽象;避免长期存在的合并分支。

抽象分支在做什么

抽象分支(Branch By Abstraction)用代码结构替代长期存在的分支:先在同一代码库中引入一层抽象,把现有实现适配到抽象之下,然后在抽象后面并行开发新实现,切换后再删除旧实现与抽象层。这样替换工作可以分多次小步提交进主干,不必维护一个长期无法合并的特性分支。它适合底层组件替换、框架升级和影响面大的重构。

基本信息

步骤引入抽象 → 旧实现适配 → 新实现并行 → 切换 → 删除旧实现与抽象
前置条件有可自动化的测试与对照验证手段,否则无法确认新旧行为一致
与特性分支对比持续集成主干,风险通过抽象与开关控制
适合底层组件替换、框架升级、大范围重构

典型使用场景

  • 数据库或存储引擎替换:在仓储接口后面并行接入新实现做双读比对
  • 框架与运行时升级:新旧调用路径共存,按模块逐个切换
  • 第三方服务更换:适配层隔离语义差异,切换前做结果对照
  • 遗留单体重构:按模块抽出抽象边界,为后续拆分服务做准备
  • 大范围算法替换:新旧算法并行运行,比对输出后再删旧实现

实施步骤

实施步骤
1. 引入抽象:按调用方需求定义接口,不预设实现细节
2. 旧实现适配到抽象,保持行为基线不变,测试全绿
3. 新实现并行开发,用对照测试比对两路输出
4. 用开关按流量比例切换,观察指标与差异日志
5. 收尾:删除开关、旧实现与不再需要的抽象层
# 第 5 步最容易被跳过,抽象层会就此长期留存

使用要点

  • 抽象层接口按调用方需求设计,不预设实现细节
  • 旧实现先适配到抽象,保持行为基线不变,确保测试可回归
  • 新实现与旧实现并行,跑对照测试比对输出,差异要有归因结论
  • 切换用开关控制,按流量比例逐步放开,并保留快速回退的路径
  • 收尾删除开关、旧实现与不再需要的抽象层,把技术债清零
抽象层是过渡产物,切换完成后应及时移除,避免留下无意义的间接层;把删除抽象层作为该任务的一部分写进计划,而不是等“以后有空”。
新旧实现并行期间两路都会产生副作用(写数据、发消息、扣配额):切换前必须确认其中一路的副作用被抑制或做成幂等,否则会出现重复写入。

易错点

  • 抽象层设计过度,替换结束后无法删除,长期保留无意义的间接层
  • 新旧实现同时对外提供服务,行为差异未做对照验证,差异只在特定输入下暴露
  • 对照验证只比结果不比副作用:写操作与消息被两路各执行一次,产生重复数据
  • 抽象边界按现有实现细节划分,新实现接入时发现接口本身绑定了旧语义
  • 缺少回退路径:切换后出现问题时无法快速退回旧实现,只能紧急修新实现

数据来源与参考

  • Martin Fowler bliki《Branch By Abstraction》(2009)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌