几个月前,玛尔塔把TPF流水线引入项目时,组里几个同事私下嘀咕,觉得这玩意儿早晚变成人人绕行的新障碍。可接下来的日子,担心慢慢消散。框架变成了背景白噪,生意照常演进,大家只在确实需要时才聊起架构。玛尔塔心想,这大概是个好迹象。

那时应用已经长了一圈新肌肉。第二位开发进组,又一家承运商接进来,客服团队有了一面监控失败订单的小仪表盘,财务部门要来一份每日对账流程。这些改动没碰应用的内核。它们只是让它更有用了。回想起来,玛尔塔发现这正是她当初盼望的那种演化——流水线在某些地方拉长,新算子长出来,自动生成的合约跟着生意一起变,可读感却出奇稳定。从上到下扫一遍,还是很像在读一条业务流程。架构一直藏在水下。至少,她此前这么认为。

打开网易新闻 查看精彩图片

丹尼尔上周多半时间都在为新接入的一家物流服务商改代码。实现走得很顺,但到代码评审时,他盯着一处改动迟疑了。那改动看着无害:一个集成替换成另一个。测试全绿,合约匹配,技术上挑不出毛病。他把屏幕转向玛尔塔:“我在这里改了流水线,但我不确定生意到底变了没有。”玛尔塔凑过去,心里清楚这正是自己预期的改动。“让你不安的是什么?”她问。丹尼尔沉默了一会儿。“我也还没想明白。”他没有合并,直接关了拉取请求。

那天下午晚些时候,玛尔塔在咖啡机旁碰见埃莱娜。埃莱娜有种本事,听几句就能问出那个刚好掐在七寸上的问题。“你看起来像在调试什么没坏的东西。”她说。玛尔塔笑了笑。“丹尼尔改了一段流水线。什么都跑得通,可他觉得生意并没变。”“那你怎么看?”“我觉得他说得对。只是说不上来为什么。”埃莱娜往台面一靠。“给我顺一遍。”

玛尔塔理了片刻思路。“订单进来。我们做校验。锁库存。扣款授权。然后转交给仓库。”“听着就是门生意。”埃莱娜说。“是像生意。但中间还夹着一些不那么像的步骤。等支付商返回,往外发消息,盯着回调做反应。”埃莱娜点了点头。“所以呢?”“假如我把流水线当‘这就是我们的业务过程’来读,有些段落读起来……不太对。”埃莱娜端起杯子:“怎么个不对法?”

玛尔塔想了想。“如果我们停掉订单校验,生意就没了。库存判断或支付决策也一样。这些是骨头的部分。”“那另外那些呢?”“如果订单到达的方式变了,或者我们换了一种接收手段——那些等待、派发消息的步骤就会跟着改,可生意的实质还在。”埃莱娜没有接话,只是听着。玛尔塔继续往下捋:“校验、库存、支付,这些步骤里嵌着业务决策。每次执行,都在替公司做一次判断。可等待回调、转换协议格式、接进新物流商的适配口,这些更像是让信息流动的管道。管道可以换,但决策必须留下来。”

这个区分听起来不新鲜,但丹尼尔那没合进来的代码恰恰把它摆上了案头。他改动的,正是一截旧的物流集成管道。可他感觉,这条流水线以往总是和生意一起变,而这次,生意纹丝不动,只有管道被拧了螺丝。他怕的,或许不是改动本身,而是如果习惯性地把一切步骤都读成“业务”,终有一天会模糊掉真正需要保卫的决策点。

埃莱娜把杯子搁下。“那丹尼尔做对了吗?”玛尔塔没有马上回答。流水线的确越来越长,新算子悄然冒出,生成的合约默默适配新场景,可当她重新从上到下扫读,那些判定库存的节点、卡住付款授权的分支,仍然像脊柱一样坚硬。相比起来,那些在边缘增减的适配口,更像皮肤上的小擦伤——会愈合,但不必动骨。她忽然意识到,丹尼尔的迟疑不是保守,而是一种架构上的条件反射:他察觉到了两种变化的时态不同。业务内核的变化,像心跳,必须全员同步感知;而基础设施的切换,该安静地发生在肢体末端,不应惊动躯干。

咖啡机发出一声提示音。玛尔塔抬起头:“他留下了大概十行没合并的代码,可留下了一个大得多的问题。”埃莱娜侧了侧头。“什么问题?”“如果连开发者都要迟疑一下才知道自己改的是‘生意’还是‘管道’,那我们的流水线是不是把两者裹得太紧了?”两人就在那儿站了一会儿。四周是键盘声和远处产品经理对着电话解释需求的声音。玛尔塔知道,第二天他们得重新翻开那条流水线,不只为了决定那十行代码要不要进主干,更为了问清楚:当系统地图逐渐庞杂,到底哪部分是生意本身,哪部分只是让生意跑得更远的轮子。

那扇拉取请求依然敞开。丹尼尔的改动仍悬在那里,像一个标注:架构藏得再深,也会在某些时刻浮出水面,要求人重新确认——我们是先看见了生意,还是先看见了代码?这个问题一旦开始问,就不会轻易回退。