---
area: "tech-engineering"
category: technology
companies_orgs:
- Chrysler
- Bell Labs
date: 2025-10-31
draft: true
guest: ''
insight: ''
layout: post.njk
media_books:
- 《Adoptive Software Development》
- 《The Programmatic Programmer》
- 《Clean Code》
- 《人月神话》
- 《Manifesto for Agile Software Development》
people:
- Kent Beck
- Martin Fowler
products_models:
- RUP
- UML
project: []
series: ''
source: https://www.youtube.com/watch?v=vJGoQigiXAE
speaker: Peter Pang
status: evergreen
summary: 本文深入探讨了敏捷开发（Agile Software Development）在实践中面临的挑战与缺陷。从敏捷宣言的诞生背景出发，分析了其作为一套理论集合而非单一理论的特性，以及在推广中被“捆绑销售”的策略。文章揭示了敏捷体系中主观预测与客观承诺界限模糊的根本问题，并批判性地审视了每日站会、结对编程等具体流程在实际应用中的低效。通过将软件工程与传统工程的PDCA模式进行对比，揭示了敏捷方法论与软件开发特性之间的“水土不服”，呼吁行业寻找真正贴合软件开发的大统一理论。
tags:
- agile-software-development
- development
- management
- organizational-culture
- software-engineering
title: 敏捷开发的困境：我们是否只是在“假装”敏捷？
---
### 敏捷开发的现状与挑战

**敏捷开发**（Agile Software Development: 一种“小快灵”的软件开发管理模式）在当今的计算机行业中，几乎被视为大家寻找已久的“大统一理论”。然而，我认为，基本上没有多少团队在做正宗的敏捷开发。这并非因为团队能力不足，而是因为正宗的敏捷开发确实存在诸多问题。因此，在很多情况下，我们实际所做的，是我们所理解的敏捷，或者说是在敏捷精神的指导下，带有团队风格、产品需求和企业文化特色的敏捷。我觉得这其实是一件好事，正如著名项目经理Atomic Energy所说：“we shall be developing agilely, but not necessarily Agile Development”，即要“敏捷地开发”，但不一定要“敏捷开发”。

### 敏捷宣言的诞生：从对立到统一

你绝对想不到的是，敏捷开发的诞生，还得感谢它的“死对头”——**UML**（Unified Modeling Language: 统一建模语言），也就是上期视频的主角。故事要从1993年说起，当时美国汽车巨头克莱斯勒的软件部门接到了一个新项目，旨在开发一个新的员工薪资管理系统，以替换集团内部多个分散的旧系统。这样一个大规模的项目，按照传统的管理模式，例如上期视频中提到的**RUP**（Rational Unified Process: 统一过程），肯定需要投入大量时间。他们的原计划是花六年时间完成系统开发、部署以及旧系统的移除。

然而，到了1996年，项目时间已经过半，新系统的开发却仍在原地踏步，基本没有进展。原本只是被招来做性能优化的新员工Kent Beck，发现了问题所在：开发流程过于臃肿。在发生了一些至今没有公开的内幕后，Kent Beck迅速上位，成为了项目主管。他引入了自己之前研究过的轻量开发理念，将项目组改造成快速迭代的运作模式。这个模式随后被命名为**eXtreme Programming**（XP: 极限编程）。十多个月后，新系统成功交付，给当时以“年”为计算单位的软件界上了一课。这也让XP模式火速出圈，成为20世纪90年代后期风头最盛的软件工程管理模式。

XP的推广大使之一，是大家熟悉的Martin Fowler，他也是多本名著的作者。Martin在世界各地宣传XP的过程中，结交了很多推广其他轻量开发模式的人。时间来到2001年，在犹他州盐湖城落基山上的一个度假村里，XP派系正在搞团建。他们觉得应该邀请一些其他轻量模式的发明人过来互相交流一下，所以Martin就从自己的朋友圈里拉来了一群人。其中就包括**Scrum**（Scrum: 一种敏捷开发框架）的发明人、名著《Adoptive Software Development》和《The Programmatic Programmer》的作者，以及大明星、《Clean Code》作者Uncle Bob等等。

但在场的还有一个人显得格格不入，他叫做Steve Mellor。他跟轻量开发基本不沾边，他发明的东西叫做**Object Oriented Analysis**（OOA: 面向对象分析），这个东西后来成为了UML的一部分。UML和它所在的RUP模式，可以说是轻量模式的头号敌人。所以部分参会者甚至很诧异地问Steve，他为什么会在这儿。在自我介绍环节，Steve还开玩笑地说：“I'm the outsider”，“I'm the spy”。

但Steve的出现才是真正的命运转折点，因为这个交流会原本没有任何主题、任何大纲。毕竟一群大佬坐在一起，每个人都有自己的观点、自己的发明，不可能有谁可以三言两语说服对方，让别人接受自己的模式更好。所以正常发展下去，就是大家互相介绍、互相恭维一下就完事了。但是作为“社交恐怖分子”，Steve非常积极地发言，他向大伙儿详细介绍了UML各种类型的图，还演示了各种作图工具。在场的其他人自然是不买账的，他们指出UML的一个大问题：很难随着代码变更而一直同步。如果要同时维护代码和图的更新，就等于制造了两倍的工作量，对于追求轻量开发的大家来说，肯定是无法接受的。

Steve的回答出乎意料，他说UML不是为了同时写代码和画图，它的终极目标是只需画图，然后用图来生成代码，连代码都不用写。还有什么比这个更轻量的吗？全场惊呼：“原来你小子才是真正的轻量开发者！”虽然大家都认为他这个想法不可能实现得了，但既然目标是一致的，那就能坐下来好好谈了。这就给讨论会引出了一个非常好的主题：与其攻击对方的差异点，不如试着找大家的共同点。我们能不能够围绕着大家的共同点，把大家的理念统一起来，而不是各做各的，让轻量模式阵营继续一盘散沙呢？

于是大家的积极性被调动起来，在经过一天的头脑风暴之后，参会的17个人集体起草了一份简单的文件。这份文件就是《**Manifesto for Agile Software Development**》（Agile宣言: 敏捷软件开发宣言）。从此，各大轻量模式不再各自为战，而是集中在敏捷体系下统一对外宣传，敏捷模式正式诞生。

### 敏捷体系的推广策略与实践中的效率问题

从敏捷宣言的诞生过程就能看出，敏捷从来都不是一个完整的理论，而是一群理论的集合。但敏捷体系在推广的过程中，从来都是被捆绑在一起，做一揽子买卖。除了抱团取暖之外，这种推广策略其实也是很有讲究的。因为敏捷是一种管理模式，所以面对的买家是管理团队，而不是执行团队。懂行的都知道，这种面向领导销售的解决方案，讲究的都是高大上、面面俱到，你得让领导安心，我这套方案包罗万象，什么情况都能处理。因为缺了啥导致事情没办好，是决定买的人的锅；如果啥也不缺，事情没办好，那只能是用的人的锅。那领导自然会选择更全面的解决方案。下面执行的人拿到这套方案，也会尽可能地全部用上，因为用了，出问题了，你还可以把锅甩到它身上；不用，后面出什么问题，都是你不用它所造成的。

但敏捷体系里的不少流程，本来就不是绝对的最优解，而是因人而异的；强行走流程，让队伍不适应，只会导致效率降低。这就本末倒置了，因为这些流程的目的应该是提高工作效率的。

比如说**每日站会**（daily stand-up: 敏捷开发中的日常短会），原本的目的是提升团队的信息同步。但你要知道，大家的工作都是相对独立的，需要了解的他人状况只占很小一部分。所以这场每日脱口秀里，大部分内容对于大部分人来说，都是无用信息。而且纯语音交流的形式就不适合所有人，比如我就是一个很依赖文本的人，我宁愿你给我发1000字的信息，也不愿意听一个60秒的语音。在站会时，通常第三个人说完，我已经忘了第一个人说了什么，我相信不少人和我类似，但是我们都只能硬着头皮继续，每天罚站15分钟。

又比如说**结对编程**（pair programming: 两人共同完成一个编程任务的协作方式），作为一种协作方式，用得好确实是能让代码质量大幅上升。但前提是组队的两个人需要同时具备很强的沟通能力，以及很能接受他人意见的心态。否则只会出现1+1<2，甚至是<1的结果。但我们都知道，这两个属性在程序员圈子里都属于SSR级别的，稀罕了。诸如此类的效率问题，在实践中往往会被归结为个人能力的问题，而不是流程本身不适合。就算管理团队妥协了，有选择地放松一些要求，或者撤掉一些流程，也避免不了下次还会掉进同一个坑里。如果效果不好，真的是个人的水平问题造成的，那还可以怪罪到个人身上。

### 敏捷的本质缺陷：主观与客观的模糊界限

敏捷体系有一个本质缺陷，才是让它无法达到理论效果的根本原因。这个缺陷就是敏捷体系对于主观和客观定义的界限过于模糊。

比如说一个**冲刺周期**（sprint: 敏捷开发中的一个固定时间周期）的制定，核心就是通过主观判断来预测任务需要多少客观成本。冲刺周期里的众多可量化的指标，如**故事点**（story point: 敏捷开发中衡量任务工作量的单位）、**速率**（velocity: 敏捷团队在一个冲刺周期内完成故事点的总和）、**容量**（capacity: 团队在一个冲刺周期内可用于工作的总时间），都是基于个人的主观预测。这些数字没有客观的、统一的量度标准。道理也很简单，因为你永远无法准确预测你没有做过的事情。

完成一个开发任务包括的时间，不只是把代码写下来所需要的时间，还有在开始写之前查看文档、读旧代码等获取知识背景的时间；写的过程中尝试多种做法、经历多次试错的时间；写完之后在**代码审查**（code review: 程序员之间互相检查代码以发现问题和改进质量的协作活动）时被人指出问题、按要求修改所需要的时间。只有负责这个任务的程序员曾经开发过基本一样的功能，他/她才有可能做出相对靠谱的预测。那如果我们已经有这么一个基本一样的功能，要么复制粘贴，要么直接调用就行了，还开发个啥？

然后就是无法避免的修bug。这种任务的存在，我见过一些开发团队想要做“事前诸葛亮”，预测接下来的两个星期会发现多少个bug，提前在冲刺周期里给它预留几个ticket，就当做是占座了。这都是很异想天开的做法，因为bug这种东西是完全不可控的。你无法预测下一个bug是不是需要紧急修复的T0级问题，是不是需要花很大改动成本的遗留问题，是不是涉及到其他系统、其他部门甚至外部服务的、无法在团队内自己解决的麻烦问题。这些bug少则完全不存在，多则可以吃掉你一整个项目周期。

如果这些问题能被正视，如果这些指标能被定位为参考数据，只用于项目规划的辅助，作为一个参考坐标，让每个开发周期都能保持一定的规律，那我们还有机会把敏捷这个体系做好。但现实不是这样，因为在项目经理、产品经理等管理层的眼里，这些数字就是硬指标，就是**KPI**（Key Performance Indicator: 关键绩效指标）。这也不能够怪领导，你整个敏捷体系都是围绕着这些数字做文章，每次会议都围绕着它们的统计报表做总结，它们不是KPI，还能有谁？

这也导致了很多团队把冲刺周期做成了“目标驱动”，而不是“预测驱动”。他们先自上而下地拿到一个要交付的目标，然后为了满足这个目标，想方设法把相关的任务都塞进去。至于故事点什么的，反正都是口头决定的，塞不下的时候，就逼着程序员更乐观地预测一下，少报一两个点就好了。只是可怜的程序员，口头上是“预测”，写下来就变成了“承诺”。但我们都知道，现实情况永远都会比预测的更复杂，所以基本都不会按照计划走。

然后你就会看到五花八门的“盘外招”。我就见识过有些项目组，因为领导比较强势，完成不了也得完成，所以全组加班赶进度成了常态。后来大家都想逃离那个组。有的组因为开发的是内部使用的系统，所以交付压力不大，一旦来不及就延期，2周变成3周，3周变成1个月，每次还都不一样，基本没什么规律。我就很好奇他们的速率是怎么算的。还有的组，产品经理和客户的关系很好，所以中途改需求也可以接受。于是他们每次发现进度不妙，就开会讨论哪个ticket可以被删掉，好减轻一下压力。结果，每次承诺的和交付的基本都不一样。我很期待哪天客户那边要是换了负责人的话，他们以后要怎么办。

只是不管什么样的“盘外招”，都解决不了“主观预测”和“客观承诺”的模糊问题。这个问题会永远成为敏捷模式在实践中的阻碍。

### 敏捷与传统工程的“水土不服”

前面提到的这些问题，其实都是有根源的。简单来说，就是对传统经验的套用的“水土不服”。我们把软件的开发叫做软件工程。既然是工程，那么对它进行管理的手段，自然也是从传统工科中传承下来的。比如圣经《人月神话》里，作者讲述他带领3000人团队开发操作系统的故事，就在多处引用了传统工科的知识和经验。

到了20世纪80年代，计算机行业开始进入个人时代，面对个人的、提供单一功能服务的、更注重用户体验的软件，打开了更大的市场，同样也意味着开启了更激烈的竞争。软件开发也开始向“小快灵”风格偏移。在工程行业，最能代表“小快灵”的，就是当年帮助日本在战后腾飞的**PDCA模式**（Plan-Do-Check-Act: 计划-执行-检查-行动）。

早在100年前，贝尔实验室的工程师Walter Shewhart发明了**统计过程控制**（statistical process control, SPC: 一种用于监控和控制生产过程质量的方法），这个框架开启了现代工程管理模式。PDCA模式的发明者，美国统计学家Edwards Deming，将Shewhart的三步流程：specification（规范）、production（生产）、inspection（检验），拓展成了更接地气的四步流程：Plan、Do、Check、Act。你可以在敏捷中看到PDCA的影子，比如一个冲刺周期，从planning（计划）、development（开发）、review（评审），到retrospective（回顾），基本上就是Plan、Do、Check、Act的一比一复刻。

但是从传统工程行业借鉴的方法，是否符合软件工程行业的需求呢？我们掰开来一个个分析你就知道了。

首先是“Plan”（计划）。在传统工程上是精准的，因为不会有人要你造一个材料未定、尺寸未知的齿轮。但在软件行业，很多需求都是含糊的、充满未知的，所以只能够凭经验预测，无法精准计划。这是前面提到的敏捷核心问题。

“Do”（执行），在传统工业上的体现是高度协同的流水线，严丝合缝的配合，因为这才是效率和安全的保障。相比起来，我们软件行业就是纯人工“踩缝纫机”，沟通成本大于开发成本。所以我们会尽量把任务拆分成互相独立、互不干扰的程度，以便大家可以独立完成。而前面所列举的敏捷的那些协作流程，一旦不适应，反而会成为累赘。

“Check”（检查）是传统工程上的重要环节，通常有成熟的检验流程和验收标准，而且具有法律意义。但在软件工程上，这个环节一直都是最随便的。有些团队将**质量保证**（QA: Quality Assurance）的结果作为最后一关，有些把“给领导演示”作为验收环节，有些纯粹就是时间到了就发布了。毕竟这是一个就算搞出世界级事故也没有法律责任，甚至都不需要赔钱的行业。对这个问题，我在【让编程再次伟大#40】视频里做了深入讨论，感兴趣的可以去看看。

而最后的“Act”（行动），在传统工程上是可以被一直传承下去，肯定能帮到后人的宝贵经验。但在软件工程上，我们的项目太有流动性了。项目和项目之间的差异可以说是非常大的，业务背景、项目需求、技术选型、代码规范，什么都可能不一样。上个项目总结出PHP开发中的坑，结果下个项目用的是JS + Go，那你就总结了个“锤子”。

四大核心流程分析完，你就能看出正宗的敏捷体系在实践中哪儿都别扭的原因了。因为本质上，它就不是以软件开发的特性为基础所设计的。我们还在等待，那个真正的、能完全贴合计算机行业的大统一理论。