TL;DR: 凡是没有涉及反馈只关注流程的,都是田园敏捷,只降低不可控,但不提高可控。
敏捷经过20年的发展,基本已经成为了软件开发行业的事实标准。现在,无论公司规模的大小,谈到项目管理基本都是默认敏捷。市面上也有数不胜数的敏捷培训、敏捷赋能、敏捷教练在推广敏捷的各种工具、各种方法、各种活动。然而,敏捷到底是什么却很少有人说的清楚。很多人会说敏捷是项目管理的方法论,这没有错,那用这个方法论要达到什么效果呢?让项目运行的更顺利?更快?成本更低?读者可以先自己回答,然后继续。
作为一名开发工程师,这些问题同样困扰了我很久,从2017年开始接触敏捷开始,直到2022年我才理解敏捷到底是什么。期间我也在各种公司经历过了各种的敏捷实践,但事实上,在我这5年的经历中,没有一次碰到了敏捷的本质。在经过正规培训、老"流氓"的教育、阅读敏捷大佬的著作之后,我终于理解了敏捷是什么,本文将为读者呈现我自己的理解。可能不对,但我自认为至少比一般的敏捷邪教大忽悠深刻一些。
敏捷的历史
这段主要由ChatGPT生成,我做了一些整理。讲敏捷历史的材料多如牛毛,这里主要是为了介绍敏捷诞生的背景,以便后面更好的了解核心。
敏捷由更早的瀑布模型发展而来。瀑布模型是20世纪早期最早的软件开发方法之一,它采用线性和阶段化的开发过程,通常包括需求分析、设计、编码、测试和维护等严格定义的阶段。每个阶段在前一个阶段完成后才开始,开发是顺序进行的。这种模型在处理复杂和变化频繁的项目时表现不佳,因为它难以应对需求的变化和客户反馈。
在20世纪80年代和90年代,一些软件开发者开始尝试采用增量和迭代的方法来改善瀑布模型的不足。他们认识到将开发过程划分为小的迭代周期可以更灵活地应对需求变化,并提高开发速度。这些努力为后来敏捷方法的兴起奠定了基础。这可以大致认为是"小瀑布"。极限编程(XP)方法是从增量和迭代开发的实践中发展而来,它强调协作、自组织团队、快速反馈和测试驱动开发。XP的提出者Kent Beck等人在20世纪90年代末将这些实践正式组织成一个方法论。XP的成功启发了其他敏捷方法的诞生。
在2001年的Snowbird会议上,一群软件开发者提出了敏捷宣言,其中包括XP的实践者。宣言强调了敏捷方法的核心原则,如个体和互动胜过流程和工具、可工作的软件胜过详尽的文档等。这个宣言标志着敏捷方法的正式出现,并推动了敏捷开发的广泛传播。随着时间的推移,许多不同的敏捷框架和方法,都在软件开发中得到应用和改进。这些框架提供了具体的指导和实践,帮助团队更好地应用敏捷原则来管理项目。
所谓的敏捷流程
从敏捷的历史中可以看到,敏捷的出现就是为了解决瀑布模式难以应对变化的问题,而需求是一定会变的,所以这也解释了为什么现在基本没有人会用瀑布了。但是,瀑布并没有死,而是在很多公司了演变成了小瀑布。很多公司,比如我之前的一家公司,只是把瀑布的周期缩短了,比如从原来的6个月变成1个月,但在这1个月的周期里,实践的其实还是瀑布的方法。这种方式并没有解决应对变化的问题,只是减少了需要应对的变化数量和大小,这也是常见的一种田园敏捷的形式,属于最初级阶段,基本只有一个名字,其他都没有。
为了继续深入,我得先介绍一下敏捷的一些流程,这里以最常见的Scrum为例,这个框架基本可以被认为是敏捷的核心,其他的大多基于它之上,以下为了方便还是称为敏捷。
先介绍敏捷中的3种角色:
-
Product Owner(以下简称PO):PO负责产品的业务价值,包括写需求,定优先级,定完成标准,并最终接收产品。一般这个角色在互联网公司里由产品经理担任,不过实际上很多业务负责人是真正的PO。
-
Scrum Master(以下简称SM):SM负责帮助团队履行Scrum框架,组织后面的各种敏捷活动,消除团队中或团队间的障碍,往往在干活的眼里最没用的人,通常由项目经理担任,也很有可能被懂敏捷的干活的兼任,一个吃力不讨好的活。
-
Developer(以下简称干活的):这里的Developer是广义的,产品、设计、开发、测试都可以算在内。主要任务就是干活,交付产品。
再介绍3种产出物:
-
Product Backlog:这是一个优先级列表,其中包括所有要开发的特性、任务和改进建议。PO负责管理backlog,并根据业务价值和优先级对其中的项进行排序。
-
Sprint代办清单:来自backlog,在planning会议上产出,记录每个sprint要做什么。号称不能改变,实际就是扯淡,后面会说怎么应对改变。
-
可交付产品增量:干活的完成的产品,通常至少是一个独立的业务功能,由PO在review会议上进行验收。
最后是5种关键的活动:
-
Sprint:一个有限时间的开发周期,通常持续1到4周,干活的在期间完成他们在planning会议中选择的工作。
-
Sprint Planning Meeting:冲刺计划会议。在冲刺计划会议中,干活的与PO协商决定在下一个Sprint中要完成的工作,选择backlog中的一些需求。
-
Daily Scrum:每日站会,应该是干活的最深恶痛绝的一种无意义会议,号称不超过15分钟,实际上经常不受控制。在这个会议上应该分享各自的进展、遇到的问题以及当天的计划,然而一般没人听,这个活动是形式主义的重灾区。
-
Sprint Review Meeting:冲刺评审会议,PO在此验收已完成的工作并找茬儿。这个会议很重要,理论上只要做到了完成的定义,PO找的茬儿只能按照新需求走。
-
Sprint Retrospective Meeting:冲刺回顾会议,形式主义第二重灾区,号称用于团队自我反思和改进的时间。团队讨论上个sprint期间的工作,探讨哪些方面运作良好,哪些需要改进,然后制定改进计划。然而我就没见过有用的,基本等于浪费时间。
好了,以上就是敏捷的Scrum框架的流程,价值观我省略了,没有任何价值。花了这么多篇幅介绍敏捷的标准流程,是为了说明田园敏捷的另一种形式------视上述流程的符合程度界定田园程度,符合的流程越少,田园程度越高。是的,就算是完全按照标准流程做,也依旧是田园敏捷。但是如果采纳关键的流程,已经可以有一些效果了,比如PO决定backlog、sprint迭代周期、sprint完成交付产品增量等等。为什么即便按照标准流程运行,也依旧被我称为田园敏捷呢?这就涉及到了敏捷的核心。在揭晓最有价值的内容之前,我们先思考一下,项目管理的目的是什么?
为什么要项目管理?
问题在本文的开头已经提出了,这里直接说我自己的结论。项目管理是保下限的,让一般人的在一起也能比较高效的协作,并且对外提供可预计的产出。单考虑项目管理本身只会增加成本并降低效率,毕竟直观的看,上面讲的一系列流程都不直接产生价值。项目管理的价值在于减少不可控因素带来的消耗,从而提高整体团队的干活效率。
所以项目管理最关键的核心是可控,目标可控,资源可控,风险可控,进度可控,质量可控,产出可控,成本可控,等等......在介绍历史环节,瀑布模式的最大的问题就是离开始越远越不可控,这些不可控叠加到后期就会导致项目崩溃。这就是为什么各种田园敏捷也依然有价值,虽然这些模式没有有效的提高可控性,但通过缩短每个开发周期,减少了不可控的因素,让不可控的因素在一段较短的时间内就被消化一次,这个周期通常不会超过1个月。这在很大程度上解决了不可控因素的积累问题,也给了各种田园敏捷模式生存空间。当然,如上面所说,田园敏捷也有高低之分,遵循的流程越多,减少的不可控因素也就越多,所以看起来越接近真正的敏捷,市面上绝大多数敏捷的培训也止步在这个阶段。
虽然流程减少了不可控,但是怎么提高可控呢?先说一种不切实际,但却真正可行的方法------提高团队素质,招募顶尖的人才,靠顶尖人才自己提高可控性。世界上仅有少数几家公司可以做到,因为这要付出大量的人力成本,并且给招的人提供很高的自由度和信任,完全仰仗人才自己的发挥,据我所知,只有Netflix号称是这个模式。马云也说过,最好的团队是至情至性,实际上就是这个道理。除了这种不切实际的办法,有没有对于普通人也适用的呢?有,真正的敏捷模式可以逐渐增加团队的可控性。
敏捷的核心
反馈
只有能通过每个sprint为下个sprint提供反馈的敏捷流程,在我看来才脱离了田园敏捷的范畴,能真正增加项目的可控性。甚至反馈本身比上面那些流程都重要,因为增加了可控性,同时也必然减少了不可控。下面说一说这个反馈是怎么产生的,具体的作用是什么,为什么反馈可以增加可控性。有3个前提条件:
-
每个sprint的时间是固定的。项目稳定运行之后,sprint周期不应该再变化,也没有变化的必要。
-
对于一个相对稳定的团队来说,每个sprint干活的数量是基本固定的,由时间决定,这里不考虑加班的情况,虽然这也是常态。
-
对于单位任务(下面把单位任务称为1个story point)消耗时间基本是固定的,比如在同一个项目中写一个标准增删改查的页面的时间应该差不多。但是这个时间具体需要多少,是一个未知数。
只要求解这个未知数,就可以比较准确的知道每个sprint能完成多少单位任务,每个sprint的可控性也就提高了。下一个sprint中,只要story point数量 * story point时间约等于sprint的中的总时间,就可以在sprint开始的时候有足够信心,认为下一个sprint是可以完成的。
求解的过程靠的就是反馈,通过对比story point的实际消耗时间和planning中的预期消耗时间,就可以让预期的数字逐渐趋近实际情况,这就是反馈产生的方式。Story point本身是一个抽象的概念,代表任务复杂度单位,对于每个团队来说都是不同的。对于干活的来说,Planning中最重要的工作就是估算该sprint中要做的每个任务的story point,让总的story point加起来约等于之前sprint的story point。之前sprint做了多少story point是在Retro中衡量产品增量得到的,所以我说不做这个事儿的Retro都是形式主义。这个数据不可能是完全准确的,但是一般来说,经过3个左右的sprint之后,团队对于自己的情况就会有一个比较清醒的认知,估算和实际的出入也会在可控范围内,于是,敏捷成功增加了项目的可控性,但这还是只有一半的核心。
技术来了
有人可能会说,3个前提很难做到,一般的项目都是前面按部就班,后面天天加班。任务耗时也千差万别,到后面任何改动都举步维艰。是的,这就是项目的常态,造成的问题的原因,大部分却不是敏捷项目管理可以解决的,而是需要一开始就设计合理的代码架构。这里我用的是代码,而非技术,因为技术架构过于粗粒度,单单决定技术栈,划分几个微服务,用什么中间件是不能解决问题的,出问题往往是代码实现的方式。这是敏捷的另一半核心,也是为什么敏捷虽然是项目管理的方法论,一开始却是由一帮写代码的开发提出,结果现在反而变成了开发不想写代码之后的退路,也是挺讽刺的。
从极限编程开始,敏捷的提出者们就开始致力于研究怎么减缓代码腐坏,让项目的生产效率在相对长的时间里可以维持稳定,TDD就是他们提出的一种解决办法,靠大量的测试,保证对代码功能的全覆盖,减少修改代码时的顾虑,确保需求更改的开发速度。这个问题的核心还是一句老生常谈的话------"高内聚,低耦合"。但怎么实践却是一个巨大且复杂的话题,在不同的技术领域也有不同的方案,本文就不多说了。关键在于,敏捷模式是需要技术配合的,不然怎么反馈也是可控性越来越低,生产效率越来越低,只不过作为项目管理者,可以通过反馈更早的发现这个状况。
Bonus:Sprint中修改怎么应对?
这是另一个极为常见的问题,虽然跟敏捷的核心没有太大的关系,但是这里也拿出来说一说。先说结论,核心就是一个字------"换"。这个问题涉及到敏捷中3个角色的分工。任何对需求的更改都应该由PO发起,但是这个理想情况,很少能有这么专业的PO,所以下面就分成PO发起和干活的发起两种情况。
如果是PO发起,那么由PO决定优先级,本质上这就是一个需要重新评估的新需求,但是由于是替换老需求,所以当前的sprint会产生一个空间。如果这个空间可以放置新需求,那么比较简单,直接放进来替换老需求就可以了,常出现在老需求还没有做的情况下。如果这个空间放置不了,比如老需求已经做了一半,那么就有两种选择。一种是可以推后,那么就直接推后到下一个sprint中,如果不能推后,不考虑加班的情况下,需要PO决定把不重要的需求挪到下一个sprint直到腾出足够的空间,再把这个需求放进这个sprint中。如果加班的话,那就看PO和干活的之间的情谊了......不过,在合理的sprint周期下,这种情况应该是少见的,如果总是出现类似的情况,说明sprint的周期不合理,或者PO不称职。
如果是干活的发起,且不需要与PO讨论,那么优先级是不变的,讨论的话就变成PO发起了。所以问题就是在当前sprint中把旧需求换成新需求,这时就只需要考虑时间。在时间超出的情况下,要么自己消化,要么在daily会议上及时提出来,大家一起想办法,除此之外,没什么别的好方法了。这也是daily会议最大的价值所在,不涉及此的daily都是形式主义。
总之,这是无法避免但应该尽量避免的问题,如果常态化,那就说明项目已经开始出现比较大问题了,也是一个警示信号。
总结
市面上介绍敏捷的资料很多,涉及敏捷核心的很少,这导致了敏捷发展到现在已经偏离的初衷。作为可能是前端开发里最了解敏捷的人,我写这篇的文章的目的是站在开发的角度,让广大的干活的了解你要遵循的规则,知道什么是有用的,什么是大忽悠,取其精华,去其糟粕,更好的应对各种田园敏捷实践。本文可能会遭到很多敏捷人士的攻击,攻击的越多就越说明戳中了一些痛点。当然,我也欢迎合理的讨论,我觉得方法论虽然虚,但在实践中还是有价值的,帮助更多人抓住价值,就是我写本文的目的。最后,推荐一本敏捷宣言提出者的小书------《敏捷整洁之道------回归本源》,我的大部分观点都出自本书,很薄,值得一看。