成熟工程师的决策树
每个工程团队最终都会面对同一句戏剧性的话。
我们不如直接重写吧。
这句话通常出现在遭遇 bug、错过截止日期,或是在阅读一个仿佛在停电中写成的文件时产生的沮丧时刻。
重写听起来干净。重构听起来负责任。
一个听起来英勇。另一个听起来像洗衣服。
但这个决定与情绪无关。它关乎风险、经济学与时间。
让我们像成年人一样一步步分析。
第一个问题
系统是否能用
不必漂亮。不必优雅。不必让你感到自豪。
它是否能用。
如果系统稳定、能产生价值,且客户每天都在依赖它,那你面对的就不是技术问题,而是营收引擎。
重写营收引擎不是勇敢,而是手术。
当系统能用但让人痛苦时,选择重构。
当系统从根本上无法满足当前或未来需求时,选择重写。
如果它能用,而你只是不喜欢它的风格,那就关掉标签页,喝杯水。
第二个问题
问题是结构性的还是局部的
局部问题表现为函数难看、模块混乱、文件过长、命名糟糕、逻辑重复。
结构性问题表现为领域模型错误、抽象破裂、架构边界错误、扩展约束无法满足。
重构擅长解决局部问题。
只有当架构本身阻碍了进展时,重写才合理。
如果你可以逐块改进而不会停止交付,那就重构。
如果每一次小改动都会引发混乱,因为基础架构有误,那你可能需要重写。
这里要诚实。大多数问题都是局部的。
第三个问题
你是否完全理解当前系统
这是大多数重写项目悄然夭折的地方。
如果当前系统令人困惑,那这种困惑往往包含了无人记录的业务规则。
遗留代码常常是生产事故的化石记录。
在没有完全理解其行为的情况下重写,你创造的不是更干净的系统,而是回归生成器。
如果答案是否定的,你并不深层理解它,那你的第一步不是重写。
你的第一步是学习。
边学习边重构。添加测试。记录行为。缩小不确定性。
只有当你能清晰地向他人解释旧系统时,才考虑重写。
第四个问题
是否允许交付速度放缓
重写会消耗注意力。它会创造平行宇宙。你需要同时维护新旧系统。
如果公司无法承受数月功能交付放缓,那重写只是幻想。
重构允许增量进步。你可以在交付的同时改进。
如果业务需要保持势头,那就重构。
如果业务有意投资于平台重置,且所有人理解其代价,那重写可以是战略性的。
但这必须是商业决策,而不是开发者的情绪波动。
第五个问题
测试是否足够强大来保护你
重构依赖于安全网。
如果你没有有意义的测试,重构会显得危险,而重写会显得诱人。
但这里有一个令人不舒服的真相。
没有测试的重写是在更高的赌桌上赌博。
如果你今天无法自信地修改系统,那你也不会神奇地在从头重建时变得自信。
先投资于测试。
一旦安全存在,决策就会更清晰。
第六个问题
痛苦是在增长还是稳定
有些代码难看但稳定。它安静地完成工作。
另一些系统则每季度变得更慢、更难改动、更脆弱。
如果变更成本在累积,那你面对的是架构债务。
在这种情况下,继续修补可能比从头开始更昂贵。
如果成本平坦且可预测,那随时间重构通常就足够了。
测量变更成本。不要猜测。
实用的决策树
下面是简化版。
它是否能用并产生价值
是
那就优先重构
架构是否阻碍关键的未来目标
是
考虑重写
你是否深层理解当前行为
否
先学习并重构
业务能否容忍交付放缓
否
重构
测试是否强大
否
在采取任何重大行动前加强测试
变更成本是否在累积
是
重写可能是战略性的
注意这一点。
重写只在通过数个关卡后才出现。
这是故意的。
情绪陷阱
重写感觉有效率,因为它能立刻消除摩擦。
你打开一个新文件夹。文件干净。抽象纯粹。你感觉自己像个架构师,而不是修理工。
但软件不是一幅画。它是嵌入现实的演进系统。
旧代码经历了生产流量。它包含的伤痕组织能保护你不再重蹈覆辙。
重构尊重这段历史。
重写则将其抹去。
有时抹除是必要的。更多时候它是自负。
更健康的模式
与其思考“重构还是重写”,不如分层思考。
用测试稳定现有系统。
缓慢提取边界。
在接口后替换模块。
用新组件绞杀旧组件。
随着时间推移,系统会变得全新,而无需戏剧性的重写事件。
业务永远感觉不到重置。工程师也永远不会冻结进度。
这不那么戏剧化。但也更不具灾难性。
令人不适的结论
大多数团队不需要重写。
他们需要纪律。
他们需要测试、更清晰的边界、更小的 pull request,以及耐心。
重写是罕见的战略举措。
重构是日常工程。
如果你发现自己想要重写,问自己最后一个问题。
我是在解决结构性约束
还是试图逃避我尚未理解的复杂性
答案决定了你是在做工程师
还是只是在情绪化地重构自己的感受。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.