可替换性:七个外部服务与一层适配

七个外部服务里只有两个在过去两年真换过,其余五个套上适配层只是多养一层代码。本文用 420 行适配层、0.67% 的代码占比、23 处调用点与 12 小时对 40 小时的迁移账,说明可替换性该给谁付钱、什么时候干脆不套一层。

适配层买的不是整洁,是下次换供应商时的选择权。

一、两次迁移,两种代价

2026 年三月中旬,陆远把搜索服务从旧供应商换到新供应商。业务代码里 23 处直接调用旧 SDK,他花了九天、约 40 小时,才把查询构造、分页游标与错误码逐处改完;上线后还漏了一处后台筛选,第二天才被用户发现。2024 年十月换模型服务时,他提前包了一层 60 行的适配器,那次只改了一个文件加三行配置,12 小时收工。两次迁移的差额,让他决定给七个外部服务都补一层,但补法要分开。

以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。

适配层买的是迁移期权,不是整洁。 它平时不产生功能,只在你要换供应商时把 23 处改动收成 1 处;不为这个时刻付钱,就得在那个时刻一次性付更多。

只有会换的类别才付全价。 过去 24 个月真正换过的只有模型与搜索两个;给从未换过的服务配双实现与影子运行,是给不会发生的迁移买保险。

适配层越薄越值钱。 每层只暴露自己用到的 6–9 个方法,替换时才知道要补齐什么;把供应商 SDK 抄一遍,等于把可替换性换成了第二个 SDK 的维护量。

二、七个服务与四百二十行

七个外部服务各有一层薄接口,每层 60 行,合计 420 行,占 62,400 行的 0.67%。方法数压在 6–9 个,只覆盖产品真正用到的能力。

服务可替换度适配层方法数上次迁移耗时
支付低(合规主体)8未迁移
邮件高6未迁移
对象存储高7未迁移
模型高912 小时(有适配层)
分析中6未迁移
搜索高740 小时(无适配层)
鉴权中8未迁移

60 行是一层的上限,不是目标。 6–9 个方法刚好覆盖产品用到的能力;方法数压不下去,说明业务真的依赖了供应商的深度能力,这时该重新评估的是「要不要换」,而不是把层加厚。

0.67% 是这笔投入的体量。 420 ÷ 62,400 = 0.67%,还不到最小 auth 模块(1,600 行)的三分之一;它换来的不是代码优雅,是 23 处调用点不再散落在业务模块里。

方法数要和调用点对上。 23 处调用点分在 7 个服务,平均每层 3.3 个;暴露 6–9 个方法,留了一倍余量给未来需求,也留出了「供应商能力比我们需要的多」这个事实。

适配层要有契约测试。 每次替换只改一个文件,前提是这个文件有测试;没有测试的适配层,只是把 23 处盲改换成 1 处盲改,风险并没有消失。

三、该给谁付这笔钱

七个薄接口不等于七份可替换性预算。双实现、迁移演练与影子运行这三件事,只给过去两年真正换过的类别做。

情形判断理由
只用一次且没有替代品不套没有第二次调用,抽象只增加一个要改的文件
供应商本身是合规主体(支付牌照)只做薄封装牌照、清算与拒付责任在供应商,代码抽象带不走
适配层会暴露 80% SDK 能力不套透传等于维护第二个 SDK,不如直接调用

支付仍有一层 8 个方法的薄封装。 它不承诺「换个支付商只改一个文件」,只承诺业务代码里不出现支付 SDK 的类型;责任边界与代码边界要分开看。

模型与搜索是唯二付全价成本的类别。 它们各有第二实现、一套迁移演练与一次影子运行;模型那次已经用上,搜索那次层还没建,付了 40 小时,这笔预算现在补上。

420 行薄接口与两份全价预算要分开记账。 420 行的维护成本属于全部七个服务;56 小时省下的是两次真迁移。不要把两者的账混在一起,也不要用「只换过两个」当借口让 23 处调用点继续散着。

判断会不会换,看过去 24 个月,不看供应商宣传。 换过 2 个、没换过 5 个;给换过的类别付全价,其余保留薄接口,这是本文唯一的分层规则。

把两次真实迁移并排看,差别不在供应商,在改动面。

项目模型迁移搜索迁移
发生时间2024 年 10 月2026 年 3 月
适配层有,60 行无,直接调用
改动面1 个文件 + 3 行配置23 处调用点
实际耗时12 小时40 小时

28 小时的差就是一层薄接口的价钱。 40 − 12 = 28,这 28 小时不是供应商难用,是 23 处调用点各自都要重新理解一遍查询语义。

搜索那次还多了一次线上遗漏。 后台筛选漏改,第二天才被用户发现;适配层的契约测试能覆盖这类遗漏,因为查询构造被收在一个文件里,替换时跑一次就知道缺哪条。

别把两次迁移的差当成供应商优劣。 同一个团队、同一套业务,差别只在有没有收口;换任何供应商,23 处调用点都会产生同样的 40 小时。

这张表也是下一次的预算依据。 再换服务时,先看它有没有适配层、调用点有几处,再决定报 12 小时还是 40 小时。

四、复算:三年净收益五十小时

把适配层的成本与两次迁移的差额放进同一张账,三年期的净收益可以手工复算。

适配层总量 = 7 层 × 60 行 = 420 行
占全库 = 420 ÷ 62,400 = 0.67%
单次迁移差 = 40 − 12 = 28 小时
三年两次 = 28 × 2 = 56 小时
年维护 = 420 × 10% = 42 行
42 行 ≈ 2 小时/年
三年维护 = 2 × 3 = 6 小时
三年净收益 = 56 − 6 = 50 小时
硬编码改动面 = 23 处调用点

50 小时是净数,不是毛数。 56 小时的迁移差额减去 6 小时维护,剩下 50 小时;按每周 40 小时算,约等于 1.25 个工作周;三年里发生两次,净收益就是 50 小时。

0.67% 的代码换 23 处调用点的收口。 如果只看行数,420 行像是新增负担;把 23 处调用点乘上每次替换的排查时间,这笔账立刻反过来。

三年两次是保守估计。 过去 24 个月已经换了 2 个;只算两次,是因为第三次可能落在三年之外,也可能被「不换」的决定省掉。

五、行动清单与复算验收

先数调用点,再决定哪一层值得加厚。

  • 列出七个外部服务,逐个写下最可能替换的三个候选。
  • 给每个适配层数出实际用到的 SDK 方法,压到 6–9 个。
  • 把每层代码控制在 60 行内,超出就拆职责而不是加方法。
  • 给每层写一条契约测试,替换时只跑这一个文件。
  • 标出过去 24 个月真换过的服务,只给它们排双实现与影子运行。
  • 对只用一次、无替代品或合规主体的服务,写下「不套」及理由。
  • 统计业务代码里对该供应商的直接调用点,目标降到 0。
  • 每次替换后记录实际工时,与 12 小时和 40 小时两个基线对照。

验收标准:任意一次供应商替换,改动不超过 1 个适配文件加 3 行配置、实际耗时不超过 12 小时、业务代码里的直接调用点为 0;任意一条不满足,就算未通过。

这层适配不承诺供应商永远可用。它只承诺一件事:当供应商要换、价格要涨、接口要停时,你改的是一个 60 行的文件,而不是二十三个业务模块。

先把 23 处调用点清零。 适配层写完不算完成,业务代码里还能直接 import 供应商 SDK,就说明这层只是摆设;清零之后,12 小时这个数字才有意义。

使用边界与实操验收

支付这类合规主体,适配层只做薄封装。 牌照、清算与拒付责任在供应商,换供应商等于换合规主体;代码层再抽象,也带不走责任与资金流。

只用一次且没有替代品的,不套。 上线时跑一次的迁移脚本、只发内部告警的 webhook,包一层只是多一个要改的文件,还多一个可能出错的地方。

适配层不能暴露 80% 的 SDK。 一旦把流式、工具调用、批处理全部透传,你维护的就是第二个 SDK;这种层不如直接调用,至少少一层翻译。

60 行是上限,不是配额。 方法数到 9 个还压不下去,说明产品用得太深,替换成本本来就高;这时应该老实依赖供应商能力,而不是假装可替换。

该停下来的信号。 适配层里开始出现供应商特有的概念,比如重试语义、分页游标、错误码树,说明抽象漏了;先补平语义,再谈替换。

关键参考与核验范围

核验日期:2026-10-26。以下文档用于核对概念与规则,本文所有数字均取自全组教学基线,不取自这些文档。

引用口径。 本文只借用上述材料中的概念名称与一般原则;420 行、0.67%、23 处调用点与 50 小时全部是教学假设,与这些文档无关。

核验范围。 上述四个入口在 2026-10-26 实测可公开访问(HTTP 200);未核验各项目的最新版本、价格与配额。

如何自行复核。 在业务代码里搜一遍供应商 SDK 的 import,数出直接调用点;再取最近一次替换的实际工时,与 12 小时和 40 小时两个基线对照。

系列导航

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「Indie」更多文章

  1. 开源项目验收:十项能力、四维评分与三种不该开源的项目
  2. 治理、fork 与退出:17 位贡献者、82% 的提交与一次改协议的代价
  3. 双许可与企业版:九家询价、两家成交与 4,800 美元