论敏捷开发原则在实践中的不可取之处

每位开发人员应该都听过敏捷原则,甚至多少都曾经使用过相关方法。而且,不少项目经理以及非开发人员都认为敏捷原则属于一种面向高复杂度问题的全面解决方案,能够搞定“如何管理软件项目”这个终极挑战。本文,作者希望整理出敏捷原则在实践中的不当操作。

在现代软件开发领域,团队在开展软件项目时需要克服一系列挑战,而且解决方案中涉及诸多元素。简单来讲,项目的规模、体量,团队规模,分配给产品的市场准备周期以及正在使用的软件堆栈等,都会对答案造成直接影响。

因此,在着手开发之前,组织首先需要制定出一套团队必须严格遵循的标准,并确保每位成员就此达成共识。这套标准必须灵活,因为具体要求会在项目的推进过程中发生变化。面对项目边界发生的波动,如果团队无法处理这些突然发生的变化,人们就会放弃原有标准犯错误,并最终导致项目进程错乱崩溃。

另一方面,如果无法跟上项目变化,开发人员也会失去工作目标、感到无聊,甚至犯下本可以避免的错误。无论是哪一种情况,项目都会遭到严重破坏,因此,组织必须在设定标准的过程中充分考虑这些影响性因素。另一个需要考虑的要点在于,即使条件已经完美,人仍然不可避免会犯下错误——这是人类的天性,而且始终如此。组织必须经常审核自己的代码,以确保所有已确定的错误都得到正确修复。这是一种常量因素,在为团队设定标准时同样需要给予充分考量。

因此,虽然看起来影响性因素很多,但其中的根本在于变化。如果没有变化,我们就无法前进;无法前进,也就无法实现目标。因此,标准必须能够适应这种不断变化的常态。

敏捷概述

上图看起来很漂亮,执行起来也不困难,但在实践中的表现却并不尽如人意。在切入敏捷这个核心议题之前,希望大家都对相关概念拥有比较明确的认知。如果各位还不熟悉敏捷化原则,请首先参阅敏捷联盟官网上的 说明 。阅读敏捷基础知识页面,确保熟悉敏捷的基本宣言与 12 条核心原则。

好了,让我们先从敏捷开发的基础知识部分开始:

敏捷 是指创造变化以及应对变化的能力。这是一种适应不确定与波动环境,并最终在其中取得成功的方式。

因此,敏捷的起点在于着手解决项目当中不断变化的问题。好的,接下来我们继续看敏捷宣言,或者四大核心价值:

  1. 个人与协作的重要性,高于流程与工具。

  2. 完成软件开发工作的重要性,高于整理文档。

  3. 实现客户协作的重要性,高于合约谈判。

  4. 对变化做出响应的重要性,高于计划遵循。

接下来,需要进行一点扩展。第一项价值主张,旨在强调推动业务需求的过程中,个人的重要性要高于流程及工具。开发者需要投入更多时间以确保软件良好运作,而非记录其中的工作原理。与客户开展更多合作,并不断听取他们的反馈,而非反复谈判并严格遵循合约内容。最后,开发者应当顺应流程变化,而非僵化在原有计划之内。

下面再来看 12 条原则。这里不列出全部内容了,只是稍稍做出点评。前三项原则与客户满意度相关,要求在短时间内(几星期到一个月之间)持续交付能够正常运作的软件。接下来的三项原则(第 4 至第 6 条)重点关注团队结构,表明业务人员与软件开发人员在整个项目当中协同努力,重视有干劲的活跃个人,并在充分发挥每个人主观能动性的前提下完成任务,同时通过面对面会议彼此交换信息。最后的六项(第 7 到第 12 条)告诉我们,要想真正实现软件开发成功,需要主理方、开发人员以及用户始终维持一致的推进节奏,实现自我组织并保持简单纯粹,最后定期对工作成果做出反思。

到这里,很多开发者肯定会发现其中存在不少矛盾之处,而且有些原则在实践当中根本行不通。接下来,首先了解大多数企业是如何在实践当中运用这些价值主张与原则的。

敏捷实践

软件团队在实现敏捷开发的过程中往往会采用几种非常标准的工具与流程:Jira(不用否认,相信大家都用过)、Sprint、用户故事、故事分值、站立会议、Sprint 计划会议、积压改进会议、Sprint 审查会议、Sprint 回顾会议、燃尽会议、Scrum、Scrum 敏捷大师、测试驱动型开发(简称 TDD)以及其它种种受篇幅所限而没必要列出的内容。

那么,这一切究竟是什么呢?首先,Jira 是一种工具,能够帮助管理大部分任务。Jira 允许规划 Sprint,为积压问题创建故事,为故事分配故事分值,为开发人员分配故事,同时推动之前提到的种种会议。整个流程,就是大家非常熟悉的 Scrum,这属于敏捷开发中的一种过程。通过敏捷基础知识页面,我们了解到 Scrum 并不是敏捷的全部。事实上,敏捷这个简单的字眼,包含着 Scrum、TDD 以及上面所列出的所有会议。

接下来,我们将更深入地了解这些概念,以及如何在敏捷范围之内共同运作。

Jira

让我们首先从 Jira 开始。在 Jira 当中,我们可以创建出“故事”。所谓故事,实际上就是一系列拥有不同名称及诉求的小任务。故事的类型多种多样,例如,用户故事可能是这个样子:“作为用户,我希望能够注册一个账户。”当然,我见过的大部分故事都不是这样的,而更多是“用……构建注册页面”,后面再跟上一大堆技术细节与附加文档。

接下来是故事,这类故事往往技术性更强。在进行初步处理之后,我们把那些无法快速解决的故事放进待办积压清单中。在这里,故事会被整理成 2 到 4 周的 Sprint 计划(具体取决于组织要求)。Sprint 实际上就是一种用于规划任务完成要求的时间表。从这里开始,矛盾逐渐出现,而整个所谓敏捷概念体系也开始崩溃。

敏捷原则告诉我们,项目成功与否的衡量标准,在于软件能否正常工作;但这并不完全正确。我们会看到,所有故事都有着对应的故事分值,这些分值则完全是从斐波那契数列中提取的任意值,用以表现对应故事的价值。数字必须来自斐波那契数列,但值可以随意选取。故事分值也可用于指示特定任务的预期花费时间,但该点的价值实际上由组织 / 团队决定。我曾经看到过某个故事分值代表一天的工作价值,而另一个故事分值则代表三分之一天的工作价值。每项 Sprint 都会记录这些点,以帮助团队成员理解该轮周期中的具体工作量。确实,这种方式能确保开发者对 Sprint 强度心中有数,也让开发者在开始 Sprint 时对大致工作量有个合理的预期。

会议、会议、开不完的会议

大家肯定注意到了,之前的清单中充斥着各种会议。先从站立会议开始,这是一类最短小的会议,也是召开频率最高的会议。站立会议中,所有团队成员都会站着参加(通常是一支 Jira 小组,内容包括当前 Sprint 任务以及所有故事)。大家会分享自己昨天做了什么、今天正在做什么,并向团队陈述任何由于要求不明或者存在其它阻碍而导致无法正常推进的问题。整个站立会议一般持续 15 到 20 分钟,具体取决于业务的繁忙程度。此外,站立会议当中也可包含燃尽会议。

下面要聊的是 Sprint 计划会议,大家也可以称其为补充会议或者评估会议。在每一轮 Sprint 之前,团队中的所有开发人员都会花费 45 分钟到 1 个小时来规划下一轮 Sprint。在会议过程中,各位成员将从积压工作中挑选出一部分,并在可能的情况下决定下一轮 Sprint 中各项任务的分值,或者是建立需要立即完成的新任务,并在必要时为任务分配优先级。

之后是积压改进会议,每位团队成员需要投入约 1 个小时时间来回顾积压清单中的所有故事,看看哪些故事应该被纳入下一轮 Sprint,哪些目前还没有办法解决。

现在,我们已经有了一套为期 2 到 4 周的冲刺计划,但还有 2 场会议等着大家。首先是 Sprint 审查会议,在这里得向其他成员介绍自己在 Sprint 期间做了什么,并评估对应目标是否切实达成。接下来是 Sprint 回顾会议,一般需要 30 到 45 分钟(或者更长,具体取决于 Sprint 的实际进展),各位成员需要陈述哪些工作进展良好,而哪些任务没能顺利推进。这些信息都将被记录在团队所选择的工具中(例如 Google Drive、微软 Office、Libre Office 等等),而后保存为团队成员都能随时查看的文档形式。

Scrum

下面要说的是之前提到的其它组成部分,包括 Scrum、Scrum 敏捷大师以及 TDD。关于 TDD 其实很值得多说一些,所以会再另开一文单独阐述。可能其中有不少愚蠢的个人观点,很多朋友可能也不同意我的看法,但这个话题本身绝对值得拿出来细讲。

回到本文,这里主要关注 Scrum 与 Scrum 流程。就技术层面来讲,之前提到的 Scrum 定义主要还是敏捷概念之内的部分,也就是“敏捷流程”。

正如之前所说,Jira 与会议中的大部分内容都来自 Scrum 框架。在 Scrum 当中,有些人会被称为 Scrum 敏捷大师。这些“大师”通常(但并不一定)属于非技术出身的项目经理,他们负责确保团队遵循敏捷实践。这些人往往负责组织各类会议,创建故事以及管理项目流程等各类非技术性工作。

具体分析

现在,我们已经了解敏捷概念中所涉及的主体内容,接下来就是分析它们如何在实践层面陷入崩溃的。如果各位有认真阅读前面的内容,肯定已经发现了一些端倪。

敏捷开发 做出了几项看似极具吸引力的承诺,首先是“个人与协作的重要性,高于流程与工具”。这当然是错误的,因为我们在敏捷过程中的第一项工作,就是把 Scrum 流程硬套在所有任务身上,并把 Scrum 敏捷大师视为救世主一样的存在。我曾经在很多团队中工作过,这帮人会严格禁止开发人员创建故事,分配故事分值或者挑选适合加入积压清单和下一轮 Sprint 中的任务。是的,没有 Scrum 敏捷大师的首肯,啥也干不了。如果请示时,Scrum 敏捷大师正在忙,那你可以玩会儿手机或者眯一下,反正啥也干不了。

这一过程同样会导致某些敏捷原则(第 4 条与第 5 条)无法起效。这两项原则希望开发团队与业务人员能够在整个项目中随时进行沟通,凭借个人内驱力构建项目,并为成员提供必要支持。首先,随时与企业管理层沟通根本不现实,而且在缺少支持的情况下,可能只会浪费大家时间。其次,开发人员很少与商务人士沟通,因为这应该由 Scrum 敏捷大师负责。Scrum 敏捷大师往往会收集业务需求并将其转发给技术团队,但这只会混淆业务范围之内的固有沟通渠道。

下面来聊聊第二条,“完成软件开发工作的重要性高于整理文档”。只要有工作经验的开发者,就知道这一原则所带来的必然结果——根本没人编写文档。这时候,代码库没有任何说明文档,当有新成员加入时,对项目的原本情况绝对是摸不着头脑。如此一来,第 8 条原则又废了:“敏捷流程应促进可持续发展。主理方、开发者以及用户都应该能够无限期保持稳定的推进节奏。”这似乎有点荒谬,因为开发人员、主理方以及用户根本就不可能无限期保持稳定的节奏,这脱离实际。多说一句,在处理任何问题时,都不可能无限期保持稳定节奏,毕竟事物的节奏总是在波动。比如,如果不做文档记录,我们的项目怎么可能可持续发展?正如之前提到,如果有新成员加入项目,但代码库又没有说明文档,我们该怎么办?答案之一是派出一位老成员,带领新人了解代码流程,但这意味着失去了一个宝贵的劳动力。另一种方式则是直接让新人开始干活,边做边学。不管怎样,这两种方式都会令新人更难融入团队,而且在很长一段时间内都无法对项目进度做出有意义的贡献。

说起可持续发展,咱们再来看看价值主张中的第 3 条,“实现客户协作的重要性,高于合约谈判。”虽然这一原则可能对业务人员有利,但对开发人员来说却是彻头彻尾的噩梦。一般来说,客户在看到解决方案之前,是不清楚自己究竟想要什么的。所以,他们会提出一整套能够满足的诉求,然后再把据此提出的解决方案彻底推翻,表示“这跟想要的不一样。”好吧,开发人员在心里把客户骂上无数遍,然后从零开始再次构建,接着重复以上过程。我参与过很多项目,而残酷的现实确实就是这样。公平地讲,并不是所有客户都这么愚蠢。不过,即使有些客户并不推翻整个解决方案,也总会时不时改变项目要求,因为他们对特定事物或者开发者所给出的方案产生了观念转变。

千百年来,客户一直就是这个样子:不知道自己想要什么,而且不断调整要求。如果硬要按照敏捷原则来,所遭受的折磨只会加倍。要知道,在这种情况下,设立的每一个 Sprint 周期,最后都会变成需要推翻重来的问题。由于 Sprint 周期只有 2 到 4 个礼拜,而且具体故事分值决定了每轮 Sprint 的具体规模与长度,因此适应 Sprint 就变得非常困难,特别是各个团队都在 Sprint 的情况下。虽然可以暂时把某些工作纳入待办积压清单,并在下一轮 Sprint 或者日常工作中处理,不过客户可能会表示反对,而敏捷原则的第 1 条要求应该坚持提供理想的软件成果让客户满意。这就又转回来了,第 1 条原则破坏了可持续发展以及之后提出的几乎所有敏捷价值主张。

接下来是第 4 条价值主张,“对变化做出响应的重要性,高于计划遵循。”之前已经提到,由于 Sprint 结构与 Scrum 流程的影响,敏捷原则在应对变化方面的表现相当糟糕。开发人员未经许可提交申请,都会引起 Scrum 敏捷大师的一顿数落,我们还能指望什么变化适应性?Sprint 结构也很有可能造成几乎相反的效果。有时,团队努力把工作量分散给更多成员,但随后由于工作量减少,扩容之后的团队就只能玩玩手机。

再来说开会。根据实际经验,敏捷团队最喜欢也最能坚持贯彻的,就是定期开会(第 6 条):“在开发团队内部,最有效的信息传达方式就是进行面对面交流。”敏捷会议永不缺席,从站立会议到 Sprint 审查会议,再到 Sprint 回顾会议,每周可能得花 3、4 个小时开会。虽然听起来好像也没什么大不了,但假设团队共有 10 名成员,每个人每周花 3 个小时开会,那相当于每周有 30 个人的工时被浪费在代码编写之外的事情上,一年就是 1500 个人工时。好吧,公平来讲,情况不至于这么严重,但时间浪费绝对存在的,而且相当严重,而这无疑破坏了第 3 条原则中提出的“高频交付能够正常运作的软件。”

在故事方面,我也有话要说。如果某个故事的分值高达 9 分,那么敏捷大师绝对会眼前一黑——这到底是什么情况?为什么故事的分值必须来自斐波那契数列?答案是,“大体正确,要比完全错误更好。”好吧,意思是给出的分值只是一种非常粗略的估计。但每当看到这样的表述,我的“废话雷达”都会报警。对,这就是彻头彻尾的废话,大致正确跟正确根本就是两个概念,我知道这么做是为了快速对某些任务的完成周期做出估算,而且大部分开发人员也没办法拿出更准确的估算结果。但是,我认为这仍然与标准有所冲突。这是从另一个角度对第 1 条原则的破坏,因为敏捷大师的心里有乐观的预期,而任何与之不符的估算分值都会让其抓狂。另一个问题是,能正常运作的软件真的代表项目成功吗?无论如何,团队都被迫通过目前手头的故事及其对应的分值来衡量成功与否。而这种作法,本身又与第 7 条原则有所冲突。

上文已经指出,敏捷化理念在 4 大价值主张以及基本原则层面遭遇失利。那么,还有其它问题吗?当然有。第 6 条与第 12 条原则(面对面交流的价值,以及工作内容回顾)对开发人员来说是一种恐怖的负担,而且根本就没有正面帮助。

我的观点是什么?

敏捷理念被强行抛售给开发人员,以提高软件的开发速度、开发质量及成果水平。但是,观察到的实际情况却正好与之相反,这只会让工作更轻松,流程更混乱。

敏捷的存在,强调的是企业对开发人员的要求以及一切控制手段。很多企业利用这种理念剥夺开发者的创作自由,或者任何其它自主发挥空间。通过参加大量无用的会议,企业能够压缩代码编写时长,从而阻止开发人员把精力投入到要求之外的尝试中。

结束语

在我看来,永远找不到真正全面的项目管理解决方案。事实上,对于大部分企业来说,敏捷反倒是个不错的选项。也有一些企业会尝试抛开规则手册,以自己的理解规划工作方式。我很赞赏企业在敏捷范畴之外着力思考,并开展创新的努力。

但是,在我看来,敏捷理念的服务对象实际是企业,而不是开发人员。而且其中提出的所有原则,对于软件企业来说违反直觉,这些原则全部指向同一个结论,即开发人员是唯一阻碍业务运作的因素。但如果企业失去了开发人员,还会有业务可言吗?而且,我很难想象会有软件企业(甚至包括其他常规企业)敢对内部的销售人员、商务人士或者任何其他部门提出同样的要求。

作为开发人员,需要尊重,并尽可能争取空闲时间。软件项目应该是一种生机勃勃的事物,这种生命力由开发人员赋予,我觉得这才是软件项目的本来面目。我认为,开发人员应该花时间对代码进行记录,无论是内部注释还是 Repo 中的 Markdown 文件。另外,会议应该以实时加异步方式进行,有事随时交流。

总结来讲,希望组织能够逐渐采用以开发人员为中心的管理方法。开发人员应该收回对开发流程的控制权,并根据自己的情况设计这一流程。