我有一个内部使用的工作仪表盘,每次打开都像在看一场信息灾难。我数过,一个页面从上到下整整摞了20个功能区块。同一个候选人信息,被以十多种不同的形式重复画在同一页上——表格、卡片、侧边栏摘要、时间轴标记,每种都在自顾自地展示,仿佛对方不存在。
更离谱的是维护逻辑。两个完全独立的弹窗竟然都能编辑同一条记录,而且它们对“这条记录是什么”的理解还相互矛盾。员工每天早晨必须执行的核心操作流,被撕裂在三个互不相邻的界面区域里,跳来跳去,毫无连贯性。所有人都知道这个页面烂透了。但我没法把它下线重做——因为同事们每天都在用它干活。
一个页面是怎么烂成这样的?没有人会一开始就设计一个20区块的怪物。你起初只设计了3个区块,然后加一个,再加一个。每一个新增都理由充分,每一个都是十分钟就能搞定的改动,背后都是一个真实用户提出的真实需求。第20个区块加进去的理由,和第4个一样天经地义。这就是陷阱:这个页面不是蠢决策的产物,而是整整17个“好决策”层层堆叠出来的后果。
最让我坐立不安的是,这堆烂摊子就是在我的眼皮底下长出来的。那些新增模块,大部分是我亲手批准的,一次一个,递进得毫无痛感,每个单独看都人畜无害。这不是接手的遗产代码,是我一手建起来的废墟。所以,我必须重写它。
但在软件世界里,重写一个正在被使用的线上界面,是最危险的操作之一。坟场里躺满了半途而废的V2版本:功能只交付了一半,悄悄弄坏了旧版能做的事,最后在恐慌中被匆匆回滚。每一个老运维都见过这种惨剧。因此,真正有趣的问题不是“怎么造出新页面”,而是“怎么赢得把它发布上线的资格”。
我给自己立了一条铁规:重写过程中绝不碰API。一个端点都不改,一个字段名都不动,一次数据库迁移都不做。新模块——我管它叫 Voucher HQ——必须完全基于旧页面已经在用的数据契约来构建。如果新页面想要的数据是旧API给不了的,那就是新页面自己的问题,它得等着,别想动后端。
最后,整个重写的后端差异,只有一个标志位:cached=1,好让新页面能请求一份更轻量的缓存读取。仅此而已。旧页面该怎么跑还怎么跑,完全不受影响。而在前端,我用了最笨也最安全的方式交付新版:新旧页面同时并存,用一条简单的链接规则进行切换。上线就是加上一个链接,回滚就是删掉那个链接。不需要倒灌数据,不需要切流量,不需要祈祷。十七个好决策攒下的地狱页面,被一条链接终结了。
热门跟贴