换一盏台灯,通常不用把家里电线重新铺一遍,因为灯和线路之间有一个清楚的连接处。
软件里的“可替换性”,也有类似意思:一部分需要更换时,其他部分尽量少跟着折腾。它不是保证任何东西都能无痛替换,而是给变化留出明确边界。
设想一个 AI 写作产品,十几个页面都直接调用同一家模型服务。每个地方都写着对方的参数、错误处理和结果格式。等服务调整,更改就像找散落的线头,很难知道有没有漏掉。
如果这些特殊写法集中在一个负责模型调用的模块里,页面只表达“需要生成什么”,以后更换服务,主要改动就有了集中的位置。这是很朴素的分工,不一定要先造一套庞大的平台。
软件工程作者 Martin Fowler 介绍过一种渐进迁移方法:借助中间层让新旧实现共存,再逐步替换,同时维持系统运行。资料:Martin Fowler
这个方法背后的意思很容易理解:搬家时有一段可衔接的过程,往往比把旧地方一下子清空,再赌新地方完全可用更容易控制。
不过,接口统一了,含义未必统一。以邮件为例,一家服务返回“已接受”,可能只表示进了队列;另一种状态才代表后续送达。如果都被产品翻译成“客户已收到”,代码看上去整齐,事实却错了。
AI 模型也一样。都能返回一段文字,并不意味着在同一任务上有同样表现。更换服务之后,关键样例仍需要比较。统一入口能缩小改动范围,不能替代质量判断。
资料也是连接的一部分。如果历史附件只存着某家供应商的地址,账号只认识对方的编号,调用代码写得再漂亮,迁移仍可能困难。真正的可替换性,还要看资料拿不拿得出、原来的对应关系找不找得到。
另一端的误区,是为还没有出现的几十种服务预先造好接口。小产品很容易因此多出一堆没人用过的规则,日常修改反倒变慢。
我更愿意把可替换性理解成“知道连接在哪里”。需要变化的地方有边界,暂时稳定的地方保持简单。等到真的换一盏灯时,不必先去拆整面墙。