本文永久链接 – https://tonybai.com/2025/04/26/13-laws-of-software-engineering
大家好,我是Tony Bai。
做软件开发时间越长,越觉得背后似乎有只“无形的手”在影响着项目进度、团队协作、系统架构甚至技术决策。有些现象反复出现,从早期的一头雾水,到后来的似曾相识,再到最后的会心一笑(或许是苦笑),让人不得不感慨其中蕴含的某些“规律”。
最近看到国外一位开发者ANTON ZAIDES总结了软件工程领域的13条“定律”。它们中有些广为人知,有些则相对小众,但都非常实用。它们虽然不像物理定律那样严格精确,但确实精准地捕捉到了我们日常工作中经常遇到的挑战和现象,堪称是工程师和管理者都应该了解的宝贵“经验法则”或“心智模型”。
今天,就让我们一起来了解和学习一下这13条定律,看看它们是如何在我们身边运作的。
注:下面文中各条定律的配图也借自ANTON ZAIDES的原文章。
定律:工作会不断扩展,填满所有可用的时间 (Work expands to fill the available time.) (任务总能拖到最后期限前完成?)
这是最著名的定律之一。简单说,如果你给一个任务设定了1周的期限,它很可能就会花掉1周;如果设定了2周,它就可能花掉2周。这常常被用来解释为什么设定“伪造”的(有时甚至不合理的)截止日期似乎能提高效率——它迫使人们在有限的时间内集中精力。但这一定律也容易被滥用,导致不切实际的期望和压力。
合理设定Deadlines是必要的,但要警惕其副作用,并结合对工作量的实际评估。它提醒我们时间管理的重要性,以及在没有明确时间约束时,任务可能无限膨胀的风险。
定律:事情总是比你预期的要花费更长的时间,即使你已经考虑了霍夫施塔特定律。 (It always takes longer than you expect, even when you take into account Hofstadter’s Law.) (估时永远不准?)
这是对软件项目估时困难最精准的自嘲。几乎所有的软件项目都会延期,即使你已经预留了缓冲时间。这一定律完美地平衡了帕金森定律:如果你因为帕金森定律而设置过短的Deadline,结果很可能是团队burnout或者项目持续延期。
软件工时评估极其困难,充满了不确定性。简单的缓冲时间往往不够。有效的项目管理需要在时间、资源和可协商的范围 (negotiable scope) 之间找到平衡,并依赖持续的沟通和实践经验。
定律:向一个以延期的软件项目中增加人力,将使其更加延期。(Adding manpower to a late software project makes it later.) (人月神话?)
这就是著名的“9个孕妇不能在1个月内生出一个婴儿”的道理。当项目延期,高层管理者常常会说:“这个项目很紧急,你可以从其他团队调配任何你需要的人!” 但项目经理的内心可能是:“请别再打扰我们,让我们专心工作就好”。
增加新人手需要时间成本:新人需要学习项目背景、熟悉代码库、建立沟通渠道。这些都会消耗现有团队成员的时间和精力,增加沟通开销,短期内甚至可能降低整体生产力。
在项目后期,尤其是面临延期时,要极其谨慎地考虑增加人手。更好的策略可能是缩减范围、优化流程或给予现有团队更多不受干扰的时间。
**定律:组织输出的设计是这些组织的沟通结构的副本。(Organizations produce designs which are copies of the communication structures of these organizations.) (你的架构是不是反映了你的团队结构?)
简而言之,你的系统架构往往是你团队组织结构的镜像。如果你的公司有独立的“前端团队”和“后端团队”,他们之间的沟通壁垒和协作模式,会直接反映在前后端接口的设计、数据格式的匹配度以及可能出现的额外“胶水代码”上。
这一定律提醒我们组织结构对技术决策的深远影响。反过来,我们也可以利用 逆康威定律 (Inverse Conway Maneuver):为了达成期望的系统架构,主动调整团队的组织结构和沟通方式。例如,想要微服务化?那就组建更小、更自治、拥有端到端职责的团队。
定律:在互联网上获得正确答案的最佳方式不是提问,而是发布一个错误的答案。 (The best way to get the right answer on the internet is not to ask a question; it’s to post the wrong answer.) (想得到反馈?先大胆“错”一个?)
这条定律巧妙地利用了人性——人们往往更乐于纠正错误,而不是回答问题。
在工作中遇到阻碍时,可以巧妙运用这一定律。例如,与其提交一个请求单等待DevOps团队处理,不如自己尝试写一个(哪怕不完美的)解决方案,提交一个Pull Request。即使写得不对,通常也能更快地获得相关人员的注意和具体的修改建议,同时也促进了知识的传递和流程的改进。主动迈出第一步,哪怕是“错误”的一步,也比原地等待更有效。
定律:任何事物(特别是人类创造出来的)90% 都是垃圾。 (Ninety percent of everything is crap.) (你做的功能多少是真正有价值的?)
这条定律是对现实的残酷揭示,有点像加强版的“二八定律”。无论是代码、想法、功能特性,大部分都可能是平庸甚至无用的。你发布的大部分功能可能对用户价值寥寥,只有那一小部分核心功能支撑着你的产品。
这要求我们具备批判性思维,勇于质疑。作为开发者,不能仅仅被动接受产品经理给出的需求列表,而要思考功能的真正价值,避免将精力浪费在那“90%的垃圾”上。这也解释了为什么“10倍工程师”并非指写10倍代码的人,而是能创造10倍价值的人——他们更懂得识别和聚焦于那重要的10%。
定律:每一个程序都试图扩展直到它能阅读邮件为止。那些不能如此扩展的程序会被可以如此扩展的程序替代掉。 (Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones that can.) (警惕功能蔓延!)
这条定律形象地描述了“功能蔓延”(feature creep) 的现象。程序(或产品)总有一种内在的趋势去添加越来越多的功能,最终变得臃肿不堪。尤其在AI时代,给任何应用加上一个聊天机器人似乎都轻而易举。
我们要警惕无休止的功能添加!保持产品的核心价值和简洁性至关重要。过多的功能不仅会增加复杂度和维护成本,还可能让用户(尤其是新用户)感到困惑,找不到真正需要的功能。需要有意识地做减法,抵制“什么都想要”的诱惑。
定律:当你有足够多的API用户时,你在合同(文档)中承诺什么都无关紧要:你系统中所有可观察的行为都会被某些人所依赖。 (With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.) (接口行为不能轻易改动!)
这条定律对API设计和维护者至关重要,它揭示了接口(API)维护的残酷现实。即使某个行为没有写在你的官方文档里,只要它是可观察到的(比如某个特定的错误返回格式、某个未公开的内部端点、某个副作用),一旦有足够多的用户,就一定会有人依赖上这个行为。
因此,API的设计和变更需要极其谨慎。任何微小的改动,即使是修复Bug或改变未承诺的行为,都可能破坏依赖者的系统。这也解释了为什么移除那些依据斯特金定律属于“垃圾”的特性如此困难——总有用户在依赖它们。进行接口设计时,要尽可能减少可观察的副作用,明确接口契约,并为变更做好版本管理和兼容性策略。
定律:在一个组织中,一半的工作是由占总人数平方根的人完成的。 (50% of the work is done by the square root of the total number of people.) (团队里的核心贡献者?)
这一定律量化了贡献度的不平均分布。例如,在一个10人的团队里,大约3个人 (√10 ≈ 3.16) 完成了50%的工作;在一个 100 人的公司里,大约 10个人 (√100 = 10) 的产出相当于剩下90人的总和。这也可以在一定程度上解释为什么Twitter在大规模裁员后没有立即崩溃。
团队规模的扩大并不会带来线性的产出增长。如果你想让产出翻倍,可能需要4倍的人员规模。这警示管理者在扩张团队时要关注人效和组织结构,识别并赋能那些核心贡献者。
定律:当一个团体的规模增加时,个体成员的生产力趋于下降。 (The tendency for individual members of a group to become increasingly less productive as the size of their group increases.) (人多不一定力量大?)
这个效应早在1913年就被发现(通过拔河实验)。团队越大,个体平均贡献的力量越小。原因主要有两个:一是动机丧失(即“社会惰化”,觉得自己的贡献不重要或难以衡量);二是协调成本增加(沟通、同步、冲突解决等开销变大)。
这也是对布鲁克斯定律和普莱斯定律的有力补充。保持小而精干的团队往往效率更高,尤其是在需要高度协作和创新的领域。明确的职责划分、有效的沟通机制和对个体贡献的认可,有助于缓解瑞格曼效应。
定律:当一个度量本身成为目标时,它就不再是一个好的度量。 (When a measure becomes a target, it ceases to be a good measure.) (警惕 KPI 陷阱!)
这是关于KPI和度量最著名的警告。一旦某个指标(如代码行数、PR 数量、Bug 修复数、用户增长数、客户满意度)被设定为考核目标,人们就会想方设法“优化”这个指标本身,而不是优化它所代表的真实价值,最终导致该指标失去意义。例如,为了提高代码行数而写冗余代码,为了快速关闭工单而不是定位根因并从根本上解决问题。
对任何单一的量化指标都要保持警惕。度量是必要的,但不能迷信指标。需要结合多个指标、定性分析以及对最终业务价值的判断,来全面评估绩效和进展。
定律:任何你需要量化的东西,都可以用某种方式来衡量,这种衡量方式优于完全不衡量。 (Anything you need to quantify can be measured in some way that is superior to not measuring it at all.) (与上一条辩证看,还是要量化!)
这一定律是古德哈特定律的必要平衡。它告诉我们,尽管度量可能不完美、可能被“攻击”,但完全放弃量化是不可取的。“没有度量,就没有改进”。找到一个(哪怕是粗糙的)量化方法,总比凭感觉行事要好。
因此,不要因为害怕古德哈特定律而彻底放弃量化。关键在于选择合适的度量维度(比如 DORA 指标、开发者体验 DevEx 等),持续迭代和优化度量方法,并结合业务背景进行解读。
定律:任何可能出错的事情,最终都会出错。 (Anything that can go wrong will go wrong.) (那个被你忽略的边缘 Case…?)
这条定律大家再熟悉不过了。它提醒我们,那些看起来概率极小、懒得处理的边缘情况、那个被你忽略的潜在Bug、那一次“应该没问题”的侥幸操作,往往会在最关键的时候给你带来麻烦。
在软件工程中,要有敬畏之心。进行充分的测试(尤其是边缘情况测试)、建立健壮的错误处理和容错机制、实施灰度发布和监控告警,都是应对墨菲定律的必要手段。不要低估任何可能出错的环节。
这13条定律,更像是前辈们用经验和教训为我们绘制的“认知地图”。它们并非严格的科学定理,但在理解软件开发这个复杂系统时,能为我们提供宝贵的视角和警示。
将这些定律记在心中,不是为了给自己设限或者找借口,而是为了让我们在日常的编码、设计、沟通和决策中,多一份清醒,多一份审慎,少踩一些坑,从而更从容地驾驭软件工程这门充满挑战与乐趣的艺术。
你对这些定律有哪些特别的感触?或者在你多年的开发生涯中,还总结出了哪些有趣的“私房定律”?
欢迎在评论区留下你的思考和故事!
商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。
© 2025, bigwhite. 版权所有.