“能用就别动”原则 —— 这是一条不成文的开发规则:除非有充分理由,否则不应修改能正常工作的代码,即使它的结构看起来并不理想。该原则基于经验观察:任何改动都会带来引入新错误的风险,而重构带来的收益可能抵不上付出的努力。根据维基百科(2026),这句俗语在工程、政治和编程中被广泛用作一种保守的变更管理策略。
要点
“能用就别动”原则(英文:“If it ain't broke, don't fix it”)是一条经验法则,提醒开发人员在缺乏充分依据时不要修改能正常工作的代码。该原则的基础是简单的统计事实:绝大多数缺陷恰恰是在修改现有代码的过程中引入的。
该原则并不是教条 —— 它更像一种启发式方法,帮助人们在不确定的条件下做决策。代码库越复杂、越缠结,一次“无辜的”改动意外破坏某些东西的可能性就越高。
根据微软公司(2024)的研究,生产环境中约60%的关键事故与近期的代码改动有关 —— 这些改动出于良好意图,但未在真实负载条件下接受充分测试。
俗语“If it ain't broke, don't fix it”源于二十世纪中叶的美国工程文化。最早有据可查的使用出自伯特·兰斯(1977),他任职于美国参议院财政委员会,反对过度监管。
在编程领域,该原则来自硬件工程 —— 在那里,把能正常工作的芯片换成新的可能带来难以预料的后果。在软件的语境下,随着软件系统日益复杂、遗留代码不断出现,这一原则得到了广泛传播。
有趣的是,在编程中,这个原则还有另一面 —— “能用,但最好别动”常常成为拒绝重构的借口,长此以往会导致技术债务的严重积累。根据咨询公司 Thoughtworks(2023)的数据,约40%的项目因对变更过度保守而遭遇严重问题。
“能用就别动”原则在特定情境下尤其适用,即错误的代价超过了变更可能带来的收益时。
在遗留代码中,如果缺少测试覆盖,任何改动都像在玩俄罗斯轮盘赌。如果开发人员无法确认改动没有破坏相邻模块,最好的策略就是别去碰能正常工作的代码。唯一的例外是严重 bug 或安全要求。
在那些不容许停机或错误代价巨大的系统中 —— 医疗软件、航空电子、金融交易 —— “能用就别动”原则是事实上的标准。任何改动都要经过多级审批和测试。
如果发布就在明天,而代码能正常工作 —— 就不要试图改进它的架构。只替换那些直接影响本次发布功能的部分。重构留到下一个迭代再做(但别忘了它)。
| 情境 | 是否应用该原则? | 替代方案 |
|---|---|---|
| 代码能用但不好看 | 是,如果没有测试 | 先写测试,再重构 |
| 存在已知 bug 的代码 | 否 | 带着测试修复 bug |
| 安全漏洞 | 否 | 立即修复 |
| 过时的依赖 | 部分 | 测试后更新 |
| 性能低下 | 取决于 SLA | 先做性能剖析,再优化 |
盲目遵循“能用就别动”原则带来的风险,不亚于无休止地重构。下面来看主要的危害。
如果每一位开发人员都遵循这一原则,代码库很快就会变成由过时方案、权宜之计和次优算法堆叠而成的“千层饼”。迟早有一天,技术债务会变得难以承受 —— 任何改动都需要数周的分析。
有时候,看似有风险的改动实际上能显著提升性能或安全性。“能用就别动”原则不应阻碍那些能带来可衡量收益的改动 —— 比如降低服务器成本、加快页面加载、增强安全性。
当团队多年不碰某些代码区域时,就会逐渐失去对它们运作方式的理解。关键开发人员一旦离开 —— 代码就变成了无法维护的遗留系统。应用这一原则时必须顾及项目的长期可维护性。
最优的策略 —— 不是盲目照搬原则,而是结合语境有意识地应用。重构是必要的,但必须安全地进行。
编程中的童子军法则:“让代码比你发现它时更干净。”如果开发人员改动一个模块,就应该改进它的结构,但要适度。不必从头重写一切,至少重命名难以阅读的变量并加上注释。
测试是安全应用“能用就别动”原则的唯一途径。如果代码有测试覆盖,任何重构都是可预期的:开发人员修改代码、运行测试,就能看出有没有破坏什么。没有测试 —— 别动;有测试 —— 放心重构。
// 示例:在测试覆盖下进行安全重构
class PriceCalculator {
fun calculatePrice(basePrice: Double, discount: Double): Double {
// 老旧但能正常工作的代码
return basePrice - (basePrice * discount / 100.0)
}
}
// 防止回归的测试
class PriceCalculatorTest {
fun testCalculatePrice() {
val calc = PriceCalculator()
assertEquals(90.0, calc.calculatePrice(100.0, 10.0))
}
}
这个例子展示了正确的做法:先测试,后重构。如果测试通过 —— 改动就是安全的。“能用就别动”原则就变成了“在测试保护下能用 —— 大胆重构”。
来看看真实的场景:在这些场景中,“能用就别动”原则既是救星,也是祸根。
开发人员发现,日期处理代码用的是 DD/MM/YY 格式而非 YYYY。这段代码从2000年到2025年一直运行正确。尽管很想“修一下” —— 他还是让代码保持原样,只加了一条注释。2026年公司升级了系统,新方案已经能正确处理世纪。过早的改动只会破坏原本能正常工作的逻辑。
一位工程师决定“改进”一段老旧但能正常工作的数据导入代码,用现代库将其替换。他没有考虑到旧库处理了一个未被记录的特殊边界情况。发布之后 —— 大量数据丢失。“能用就别动”原则被违反了,代价是整个团队花费两周时间恢复数据。
常见问题
不是,盲目遵循该原则会导致技术债务累积和项目灵活性丧失。最佳做法是在改动风险大于潜在收益的情形下有意识地应用它。重要的是针对每个具体情况单独评估。
在发现安全漏洞、影响用户数据的关键 bug,以及需要更新存在已知漏洞的依赖时,必须打破这个原则。在这些情况下,不作为的风险高于改动的风险。
唯一安全的方式是先用测试覆盖代码(表征测试),然后以小步重构并持续运行测试。如果没有测试保护,“能用就别动”原则必须被严格执行。
有经验的开发人员是有意识地打破原则 —— 他们能看出当前实现中那些不明显的后果:未来的 bug、性能瓶颈、扩展问题。他们的决定基于经验,而非对变更的恐惧。
平衡来自测试文化与代码评审。如果代码有测试覆盖,重构就是安全的;如果没有,任何改动都应当控制在最小必要范围内。“能用就别动”原则不是禁止改动,而是要求自觉。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。