第2章 敏捷开发方法——摸着石头过河的智慧

第2章  敏捷开发方法——摸着石头过河的智慧

2001年2月11~13日,17位志同道合的软件开发的实践者自称为“中年白肤色男人帮”(middle-aged white guys,mawgs),聚集在美国犹他州著名的滑雪胜地雪鸟城(Snowbird)滑雪,享受美食,同时花两天时间讨论更好的软件开发方法。这17位软件开发的实践者有一个共同的理念:应该找到一个替代文档驱动的重量级软件开发过程的新方法。这17位软件工程师(现在应该称他们为敏捷的领军人物)代表了敏捷运动的各种流派:极限编程(Extreme Programming,XP)、Scrum(本书的重点)、动态系统开发方法(Dynamic System Development Management,DSDM)、自适应软件开发(Adaptive Software Development)、水晶项目管理(Crystal)、特性驱动开发(Feature-Driven Development)和实用编程(Pragmatic Programming)等。

虽然这些人都认同轻量软件开发过程,但让一群独立思维的聪明人在具体做法上达成一致是一件很难的事。聚会时间临近结束,大家还是争论不休,这时有人提出了一个求同存异的折中建议:把我们17个人都认同的理念整理出来,写在白板上。最后白板上只留下了4条,他们把这4条称为“敏捷宣言”,把自己的组织称为敏捷联盟。“敏捷”一词从此替代了轻量过程开发,成为软件业出现频率最高的词。选择敏捷(Agile)一词还是有些争议,有人担心这个词会被误解为无序(这个担心到现在来看还是有些道理的)。一位来自英国的绅士甚至担心美国人不知道如何发Agile的音。当然最终大家都非常满意聚会的结果,每个人都觉得他们做了一件有意义的事。但谁也没有意识到,这短短几句话,成了近20年来最重要的软件文献,它推动了一场软件工程的革命。

2.1 经常被错误解读的敏捷宣言及敏捷原则

下面是敏捷联盟认可的敏捷宣言的中文版(http://agilemanifesto.org/iso/zhchs/manifesto.html)。

敏捷软件开发宣言

我们一直在实践中探寻更好的软件开发方法,

身体力行的同时也帮助他人。由此我们建立了如下价值观:

个体和互动 高于 流程和工具

工作的软件 高于 详尽的文档

客户合作 高于 合同谈判

响应变化 高于 遵循计划

也就是说,尽管右项有其价值,

我们更重视左项的价值。

正如一位宣言作者所言,这个宣言是一个战斗口号:它明确表达了我们支持什么及我们反对什么。这个宣言也清楚地指出什么是敏捷,什么不是敏捷。

2.1.1 敏捷宣言是价值宣言

敏捷宣言是一个价值宣言,它强调了在开发过程中我们要关注什么,正确的优先级应该是什么。

1.个体和互动高于流程和工具

人、过程、工具和成功开发软件系统的关系是个老话题了。如果给你一个选择:谁更有可能开发出好的软件产品?是10个勤奋、能干的软件工程师,使用他们各自的工具,每天在一起协调配合工作,他们之间存在有效的沟通互动;还是10个能说不能做的牛人,他们共有一个明确的定义过程,可以用最好的工具,坐在最好的办公室。如果要开发的产品有一定的复杂性的话,我会选择前者。人和能保证他们在一起有效工作的机制是开发出好产品的最重要因素,没有这一点,工具和过程不会发挥它们的作用。这绝不是说工具和过程不重要,但软件开发是高智力活动,在开发复杂系统时,人更加重要。同时团队成员间及时沟通互动,比仅仅通过文档工具进行沟通更加重要。当然在一定程度上,工具和过程可以帮助建立维护保证人一起有效工作的机制。

2.工作的软件高于详尽的文档

问一下你的用户,他是更愿意看一个200页的文档描述你要开发的产品还是软件本身?我猜绝大多数用户都会选择软件本身。如果是这样的话,我们为什么不能通过快速开发出软件,让用户了解项目进展情况?大多数用户更容易通过观察软件演示来理解开发的产品,那些复杂的内部技术实现图、抽象的使用说明,恐怕会让用户望而却步。文档有其价值,它可以帮我们理解系统是如何被开发的及选择这种开发方法的原因(这对支持后期维护至关重要),文档也可以指导用户使用开发的系统。但文档不是软件开发的主要目的,否则我们就应该叫文档开发了。文档的目的,在某种程度上是为了帮助我们开发出工作的软件。

3.客户合作高于合同谈判

和客户打交道可能会是一件痛苦的事,因为他们通常没能力准确地描述出产品需求,他们从来不能一次把事情讲清楚,他们还经常改主意。但只有他们能告诉你他们需要的东西,只有开发出的软件得到他们的认可,你才能最终收到合同款项。这是每个软件企业必须面对的现实。通过合同明确各自的权利与义务,并且保护你的利益也很重要。但合同谈判不能替代和客户的沟通,成功的开发团队会把客户当成团队的一部分,通过迭代开发模式不断获取客户的反馈,在开发中逐步理解客户的真正需求,并和客户一起加深对产品价值的理解。

4.响应变化高于遵循计划

变化是软件开发过程中一个常态:客户对业务领域的理解加深会导致变更;商业环境的变化会导致变更;技术的变化也会导致变更;人员的变动也会带来变更。如果你的软件过程不能有效地处理变更,那么这些变更有可能把项目带到绝境。计划很重要,但计划必须有其伸缩能力,我们必须能及时抛弃过时计划元素,更新计划响应变化。项目的目的不是为了符合计划,而是用计划指导我们开发出对客户有价值的产品。

有意思的事是几乎所有人看到这4条都不会提出异议,第一反应很可能是“当然应该这么做”。可惜在传统开发模式下,在盲目强调过程符合的文化下,这些价值观都没有真正得到体现。

另外我们也要避免从一个极端走到另一个极端:完全忽略右项的价值,在敏捷的名义下,变得完全随意,没有过程,没有计划,这样的敏捷不会成功。

敏捷宣言讲的是方向性的东西,它是一个里程碑式的宣言。

2.1.2 敏捷的12原则背后的故事

在雪鸟城聚会后的几个月里,这些敏捷领袖通过邮件和wiki沟通,写出了12条原则,给出了实现宣言4个价值观的指导理念。这里我觉得很有必要对这12条原则逐一做个简单解释说明。为了让大家能准确理解每一条原则,我将英文附在里面。

(1)尽早、持续交付有价值的软件是我们满足客户的最优先考虑。(Our highest priority is to satisfy the customer through early and continuous delivery of valuable software. )

我们在第1章中讨论了先知后行(定义好一切再开始软件开发)的弊端,尽早、持续交付软件增加了开发团队和产品团队(客户)的沟通机会及质量。知行合一的增量开发也能让用户尽早开始使用开发出的有价值的系统功能特性。

在规划迭代时必须按照优先级安排,尽可能先为客户提供最有价值的功能。通过频繁迭代与客户形成持续的良好合作,通过及时反馈来提高产品可用性及质量。这个原则也告诉我们,团队应更加关注完成和交付具有用户价值的需求功能,而不是孤立的任务。

(2)即使到了开发的后期,也欢迎需求变更。敏捷过程利用变更为客户创造竞争优势。(Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.)

从来没有无缘无故的需求变更,变更的原因经常是开发中的需求功能已不能有效地满足用户的需要。我们要做的是,拥抱变更但要将变更成本降到最低。敏捷能让我们做到这一点,而瀑布模式则无法做到这一点。

(3)频繁交付可以工作的软件,交付间隔越短越好,可以从一两周到一两个月。(Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter time scale.)

我们在第1章讨论了反馈的价值,频繁交付工作的软件给利益相关人提供一个很好的沟通反馈平台。这些反馈可以让开发团队和产品管理团队及时对产品的方向做出调整,也可以让开发团队及时总结、对使用的过程进行调整。和瀑布开发模式不同,敏捷开发模式对开发阶段没有什么重要的分割,不是接力的需求阶段,然后是分析阶段、架构设计阶段、编码测试阶段等。敏捷团队是一个跨职能的团队,在项目开始后,上述瀑布阶段的工作会同时开始。

(4)在整个项目开发期间,业务人员和开发人员必须可以天天随时沟通、一起解决问题。(Business people and developers must work together daily throughout the project.)

复杂软件项目不会完全依照项目前期制订的计划执行,各种不可预测的因素会产生实际和计划的差异。开发人员和产品团队(客户、市场人员、产品经理等)有效、频繁交互是及时发现并解决问题的最好手段。如果一些重要的利益相关人不在本地,那么我们需要建立沟通工具平台,支持异地人员能够随时和团队进行有效沟通。

(5)围绕一群有动力的个人进行项目开发。给他们提供所需要的环境和支持,并且相信他们会把事情做好。(Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.)

这些年来,我发现一些国内企业有这样的不切实际的想法:似乎通过引入符合CMMI、ISO等要求的过程,就能让一群能力不是很强的人良好地完成软件开发工作。似乎过程真的可以完全替代人,人完全变成可替换的东西。他们忽略了软件开发和制造业的差异,软件过程和流水线过程的差异。敏捷强调团队的重要性,敏捷团队是由一群自律、有团队精神的人组成的,他们乐于协调工作、互相学习。他们谦虚谨慎相互尊重,在敏捷理念里,人是软件开发成功的最重要因素。管理者的重要工作是激励每个人发挥出他的最大潜力,让个人的目标和团队的目标一致,以一群主动的个人为中心构建项目,同时为他们提供所需的环境、支持与信任。

(6)对一个开发团队来说,面对面沟通是最高效的传递信息的方法。(The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.)

行为研究显示,对一个小团队来讲(小于10人左右),面对面再加上一个白板就是最有效的沟通传递信息方式。这种方式比通过文档、邮件、电话沟通都更加有效。Scrum中的每日站立会议就是实现这个原则的一个实践。

(7)工作的软件是软件开发中首要进展度量指标。(Working software is the primary measure of progress.)

软件开发中完成了多少符合客户要求的功能应该是项目进展状况的重要度量指标,而衡量任务完成情况的所谓挣值其实很难代表项目真正的进展情况。我们比较容易度量大部分工作进展,如搬运1吨的煤,只要称下已经搬运煤的重量就知道完成多少了。而对于软件来说,在软件没有完成编码、测试之前,我们不能因为代码编写了多少行,测试用例跑了多少个就去度量这个功能是否完成。度量这个功能是否完成的唯一标准应该是这个功能可以工作了,用户已经可以用它了。

(8)敏捷过程提倡可持续的开发。产品的赞助者、开发者和用户应该能够保持一个长期的、恒定的开发节奏。(Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.)

IT行业是一个很辛苦的行业,过劳死、亚健康往往和IT人士联系在一起。跑马拉松比赛,没人能够一直像跑百米一样地冲刺,否则你一定会倒在中途。让一个团队连续几个月天天加班,也很难开发出高质量的产品。软件开发主要是脑力活动,像我每天集中精力有效工作的时间也就6小时,过了这个界线,脑子就明显钝化了。

国内IT行业认为软件开发中加班是天经地义的,不加班反而不正常,敏捷也不会改变这种常态。可敏捷提倡的是可持续开发,开发速度不应该随着迭代的任务不同而不同。开发活动不应该是突击行为,因为你不可能指望突击完成一个项目后就轻松了,下一个项目会接踵而来,当然下一个项目依旧会让你再次突击。听起来长期加班也可以是所谓“持续开发”,但是这种状况是不可能持续恒定的,因为人会疲劳、厌倦,健康变坏,长期这样的话也会影响家庭幸福。软件开发的节奏意味着阶段、活动的可预测性:固定的迭代周期、固定回顾会、固定评审会等,都会帮助团队形成自己的开发节奏。

这也是我不喜欢将Sprint翻译成“冲刺”的原因,因为我们不可能用冲刺的方式来跑马拉松。在Scrum中,Sprint其实强调的是周期短,而不是跑得快。所以本书中,我将Sprint翻译成“迭代”。

(9)不断关注卓越技术及优秀设计能增强敏捷力。(Continuous attention to technical excellence and good design enhances agility.)

一个高质量的代码库比一个低质量的代码库更容易被理解、维护和完善。卓越技术应该是敏捷团队、敏捷人永远追求的东西。极限编程给我们提供了很多好的办法,如代码的重构、测试驱动开发、持续集成等。很多架构设计方法、数据库设计方法、技术评审方法也应该成为敏捷团队遵循的指南。这些好的技术实践可以加强产品敏捷能力,很多原则、模式和实践也可以增强敏捷开发能力,特别是解决敏捷的天敌—带病迭代的问题。

(10)简于形——是最大化地减少不必要工作的艺术——这是敏捷精髓。(Simplicity—the art of maximizing the amount of work not done—is essential.)

这一条是我最喜欢的敏捷原则,也是最难翻译的。敏捷是一种在可能限度范围内求全的艺术,但不是追求完美的艺术。如开发团队不可能预期后面需求会如何变化,所以不可能一开始就构建一个完美的架构来适应以后的所有变化。敏捷团队不会去构建明天的软件,而会把注意力放在如何用最简单的方法完成现在需要解决的问题。如果你已经预计到了肯定存在的需求扩展点,是否一开始就考虑呢?团队可以需要根据自己的最好理解去决定是否考虑,如果深信在明天发生了这个问题也可以很容易处理的话,那么就最好先不考虑。尽量只做正好够(just enough)的东西以及在恰当的时间(just in time)做决策是敏捷的核心实践之一。希望读完本书后,这条原则能够融入你的思维体系中。

(11)自我组织的开发团队能够逐步摸索出最适合的构架、需求和设计。(The best architectures, requirements, and designs emerge from self-organizing teams.)

这句话大概是最有争议的原则。在翻译“best”时我没有用“最好”而是用了“最适合”。自我组织管理团队是敏捷主要的实践之一,这个也是在国内实施敏捷的一个难点,很多企业都绕过了这一实践。后面章节中,我会对这个话题做深入的讨论。在自我组织管理团队中,管理者不再发号施令,而是让团队自己去寻找最佳的工作方式来完成工作。自我组织团队的第一个要素就是必须有一个团队,而不仅仅是一群人。一群人是一帮在一起工作的人,他们彼此之间并没有太多的沟通协调,他们也并不视彼此为一体。项目一开始,我们就会组建“团队”,但很多时候其仅仅是由构架师、需求人员、开发人员和测试人员组成的一群人而已,而不是一个团队。

团队的形成必须经历几个时期,只有在经历了足够的磨合后,成员才会开始对团队共同的工作理念与文化形成一个基本的认识和理解。团队内会逐渐形成规矩,而且这些规矩是不言而喻的。例如,每个人都知道上午9点来上班,都会主动询问别人是否需要帮助,也都会去主动和别人探讨问题。如果团队成员之间能够达成这样的默契,那么这个团队将成为一个真正高效的工作团队。在这样的团队中,成员之间相互理解,工作效率非常高。在自我组织团队中,团队成员不需要遵从别人的详细指令。他们需要更高层次的指导,这种指导更像是一个目标,一个致力于开发出更好软件的目标。总之,自我组织团队是一个自动自发、有着共同目标和工作文化的团队,这样的团队能够逐步将团队能力最大化,这样的团队才有可能一起摸索出最合适的技术解决方案。

(12)每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后对自己的做事方式进行必要调整。(At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.)

敏捷中的过程改进比传统环境下更及时、更有效。每个迭代结束后,团队会进行得与失的分析,固化好的做法,调整出问题的过程环节。针对性的改进可以很快在下个迭代中进行,不断提升团队的开发能力。本章后面章节我们会讨论敏捷过程的特征:它不是一个预定义的过程,而是一个基于经验的过程,团队通过不断的实践、反省、调整来改进所执行的敏捷过程。

希望你能再看一下宣言的4条内容,好好琢磨一下这12条原则。你觉得软件开发应该遵循这些原则吗?你认为这些表述是一些不现实的目标,还是简单的常识—本该如此?真正理解这些原则能够帮助你学会敏捷思维,而不仅是照葫芦画瓢地做敏捷。

敏捷12条原则

 

1.尽早、持续交付有价值的软件是我们满足客户的最优先考虑。

2.即使到了开发的后期,也欢迎需求变更。敏捷过程利用变更为客户创造竞争优势。

3.频繁交付可以工作的软件,交付间隔越短越好,可以从一两周到一两个月。

4.在整个项目开发期间,业务人员和开发人员必须可以天天随时沟通、一起解决问题。

5.围绕一群有动力的个人进行项目开发。给他们提供所需要的环境和支持,并且相信他们会把事情做好。

6.对一个开发团队来说,面对面沟通是最高效的传递信息的方法。

7.工作的软件是软件开发中首要进展度量指标。

8.敏捷过程提倡可持续的开发。产品的赞助者、开发者和用户应该能够保持一个长期的、恒定的开发节奏。

9.不断关注卓越技术及优秀设计能增强敏捷力。

10.简于形—是最大化的减少不必要工作的艺术—这是敏捷精髓。

11.自我组织的开发团队能够逐步摸索出最适合的构架、需求和设计。

12.每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后对自己的做事方式进行必要调整。

那么什么样的开发模式称得上是敏捷过程呢?敏捷的4条价值宣言及12条原则给出了明确标准。如果一个开发模式是在身体力行这些宣言及原则,那么它就是敏捷,否则就不能称之为敏捷。本章第一段落里提到的方法,是业界一些常见的敏捷开发模式。

当你读完这本书以后,可以回来再看一下敏捷宣言及原则。也许那时你的体会和理解会更深一些。

2.2 敏捷开发架构与Scrum:调整中增量开发

1986年2月,两位日本人Takeuchi和Nonaka(1986)在哈佛商业评论上发表一篇题为“一个新的新产品开发游戏”的文章,提出了一个类似于英式橄榄球(RUGBY)比赛的产品开发模式。他们没有想到,几年后这篇不起眼的文章给3位美国软件开发经理带来了他们需要的灵感。Jeff Sutherland、Ken Schwaber和Mike Beedle不约而同地将文章中的产品开发模式应用在他们管理的软件项目上。10年后他们在自己的经验基础上定义了Scrum的框架及实践(Schwaber,2004, 2007; Schwaber et al.,2002; Sutherland et al.,2011)。3位作为敏捷初期的探索者,也参加了2001年2月在雪鸟城的聚会。今天绝大多数应用的敏捷过程是Scrum或Scrum和其他方法(如极限编程、传统方法等)的结合。本书中描述的敏捷管理活动多以Scrum为核心,而工程活动则多以极限编程的方法为主。但我不局限于这两个方法,只要是经过验证的相关有效实践,我都会参考。

2.2.1 敏捷开发架构

在介绍Scrum之前,我觉得很有必要介绍一下Jim Highsmith(另一位敏捷宣言的签名者)提出的敏捷开发架构(Highsmith,2011)(见图2-1)。这个架构体现了敏捷的核心理念,在这个架构下,我们可以更好地理解Scrum。

0201.tif

图2-1 敏捷开发架构图

如图2-1所示,敏捷开发应该包含以下5个不同阶段。

(1)产品愿景阶段:其主要工作是确定产品的愿景及大概范围,项目目标以及约束条件(做什么),同时明确团队相关成员(谁来做)及协同工作方式(如何做)。

(2)推测阶段:围绕需求特性建立产品发布计划,主要工作包括:收集分析初始需求,估计开发成本等信息,考虑风险缓解策略,建立一个迭代和需求特性基础上的开发计划。

(3)探索阶段:计划并在较短周期内成功提交一个产品功能特性子集,并不断寻求降低项目的不确定因素。这个阶段主要完成3个关键活动。

  • 开发团队通过遵循有效的技术实践及有效任务管理,提交规划的需求特性子集。

  • 建立并不断完善一个协作、自我组织的项目社区。

  • 管理和客户、产品管理团队及其他重要利益相关人的沟通,加深对产品价值及约束条件的理解。

(4)调整阶段:开发团队和客户及其他重要利益相关人一起评审迭代完成的需求功能特性(工作的软件),对产品的需求做出调整。同时团队也会从迭代过程性能(如效率)及项目状态的角度回顾刚刚结束的迭代,根据情况调整迭代过程和发布计划。本阶段活动的结果会用来帮助更好地做好下个迭代的工作。

(5)关闭阶段:每个项目都有个结束点,结束点也是总结点—总结经验教训、优秀实践,获取新知识的总结传承。

注意图2-1中推测(speculate)、探索(explore)和调整(adjust)之间的闭环,这3个词较为准确地表达了敏捷核心理念,表达了知行合一的精髓。这3个词代替了瀑布模式中的计划(plan)、执行(do)和纠错(correct)。用推测而不是计划,更明确表示在这个阶段我们并不知道一切,当我们在迭代中获取更多信息后,调整是件自然的事。用探索而不是执行则体现我们在摸着石头过河,边开发边获取更多的信息。调整不是纠错更明确表示一开始我们并不知道什么是对的,也就是初始计划不见得是正确的。调整后我们会带着更深的理解及更多的信息进入下次探索(迭代)。这3个阶段不断地循环,直到将一版新的对用户有价值的软件产品提交给客户。在本书第4章中,我会更加详细地介绍这5个阶段的内容。

在传统瀑布开发模式下,“计划-执行-纠错”意味着早期项目一般不会偏离计划,但在项目后期往往会跳出计划的轨道。而“推测-探索-调整”则恰恰相反,我们预期项目不会按预测的进行,但后期则会越来越准。

但另一方面我们也应该意识到,敏捷架构也有一点传统方法的影子:推测有计划的影子,每一次探索的结束都有里程碑的影子。在实际操作中,敏捷过程往往会或多或少吸收一些传统方法的实践。这个平衡度的把握是由需求清晰度及技术稳定度来决定的。

为了让大家能够更深入地理解Scrum,还需要用些篇幅介绍产品开发的两类过程:定义的过程(defined process)和经验性过程(empirical process)。定义的过程往往描述一个可重复的生产过程,只要严格遵循过程中定义的每一步,我们就能生产出满足质量要求的产品,它是一个可预测的过程。在制造业,人们都会尽可能地使用第一的过程,这样才利于批量生产并能大大减少成本。但当开发复杂产品时,有时我们没有办法明确过程中的步骤,强制执行定义的过程反而会带来由于不定因素而造成的大量返工。这时,实验性过程就是一个好的选择。

实验性过程有3个关键支撑点。

(1)透明(transparency):整个开发过程中所有活动透明,并且所有人对完成标准理解一致。例如,如果我们说某个需求项已经完成,那么所有人的理解都应该是一样的。不能是有些人理解为仅仅是代码已完成,而另一些人的理解是代码已完成,并通过了代码审查、单元测试、集成测试和验收测试。透明是实现另外两个关键支撑点的基础。

(2)审查(inspection):在过程中,我们需要不断审查过程中的差异及问题,很明显,透明是审查的先决条件。检测的频率和过程活动的执行有密切关系,有效的审查也要求审查人员必须具备必要的产品、技术、管理和过程的相关技能。

(3)调整(adaptation):在过程中,当审查出的问题会影响到过程目标时,我们需要及时调整相关过程或过程相关因子,将损失降到最低。

代码审查就是一个实验性过程的例子。当一位不是很有经验的程序员完成一个代码模块后,项目经理会要求对模块做一次代码审查。几位有经验的程序员会依据代码标准对其进行评审,当然他们对这些标准非常熟悉。评审中发现的问题及建议会用来完善该代码模块,也会用来完善评审过程、标准,它们也会帮助这位经验不足的程序员提升编程能力。

Scrum是为了在复杂场景(图1-4中的“困难”和“复杂”类项目)下开发出有价值的产品而建立的。复杂场景往往意味着不确定性、不可预测性,也就是说我们很难建立一个步骤明确的过程,指导我们开发出客户需要的软件。定义的过程对这类项目是非常不适用的。对于复杂项目来讲,实验性过程是个更好的选择。Scrum就是一个实验性过程,它给出了一个简单但有效的执行知行合一的架构,是多数敏捷组织的首选敏捷方法。

2.2.2 用一分钟来解释一下Scrum以及Scrum中的3个角色、3个文档和5个会议

那么Scrum到底有多简单呢?我可以用7句话,用不到一分钟的时间把它概括一下。

(1)产品经理(product owner)负责建立并维护一个按优先级次序排列的、反映客户期望的产品需求列表(product backlog)。

(2)在迭代(sprint)计划时,团队从需求列表中优先级高的需求项中选取一小部分,放入迭代需求列表(sprint backlog)中,并决定如何开发这些需求功能。

(3)团队在固定的时间周期内完成一个迭代,通常是2~4周,团队每天会在一起评估项目进展情况(daily scrum)。

(4)在这个过程中,Scrum过程经理(Scrum master)会让团队关注迭代目标的实现并遵循Scrum实践。

(5)在每次迭代结束时,团队完成的代码是可以提交的:可以直接让客户使用,或者可以展示给客户或用户代表。

(6)迭代的最后两个活动是迭代评审(sprint review)和迭代回顾(retrospective),根据反馈,对产品及团队工作方式(过程)做优化调整。

(7)在下个迭代开始时,Scrum团队(Scrum team)又会从产品需求列表中选取一部分优先级高的需求项,开始新一轮的开发工作。

图2-2给出了Scrum一个大的管理框架。

如前所述,国内大部分人把Scrum中的Sprint直译成“冲刺”,我不是很喜欢这个翻译。因为冲刺这个词给人的感觉像是在跑短跑,而这是和第八条敏捷原则相违背的。这条重要的原则指出:“敏捷过程提倡可持续的开发。产品的赞助者、开发者和用户应该能够保持一个长期的、恒定的开发节奏。”软件开发是马拉松,按百米跑的冲刺速度来跑马拉松会让你很快累趴下。在本书里,我用迭代来表示Sprint,大家把它理解成一个短周期的开发就行了。在第5章,我会详细介绍Scrum中的实践。

有人把Scrum简单解释为3个角色、3个文档和5个会议。

0202.tif

图2-2 Scrum管理框架

1. Scrum管理框架中的3个角色

在介绍Scrum角色之前,先讲一下著名的猪和鸡的故事。一只有经商头脑的鸡找到一头聪明的猪,提出合伙开一家火腿和煎蛋快餐店。猪想了一下说:“好像不太公平,我们介入的力度差别太大,我出的是身上的肉,你出的是每天下的蛋。”

Scrum的角色就是产品开发中的猪,他们是产品经理、Scrum过程经理和Scrum团队(Scrum team)。

顾名思义,产品经理最主要的责任是保证团队开发的功能特性对客户是有价值的,具体来讲,他需要做以下5件事。

(1)建立产品的愿景,也就是产品给客户带来的价值。

(2)建立维护产品的发布计划/版本计划(release plan)。

(3)及时收集用户反馈、优化产品需求。

(4)确定每条需求项(用户故事)的价值及优先级。

(5)明确每个需求项的验收通过标准。

Scrum过程经理比较特殊,在传统方法中是没有这个角色,所以这是个经常被误解的角色。一个称职的Scrum过程经理能在3个方面起到重要作用:让团队的关注点始终在实现客户价值上;让团队在每个迭代中不受干扰(大家都知道封闭式开发能够保证效率,Scrum的每一次迭代就是不需要团队成员住酒店的封闭式开发);帮助产品经理和团队在Scrum的框架下做好各自的工作,并做到有效沟通。为了实现这3个目标,Scrum过程经理需要做好下面一些工作。

  • 建立、改进适用于团队的Scrum过程。

  • 推动敏捷实践及有效开发实践在开发中的有效应用。

  • 推动团队问题障碍的解决。

  • 帮助培育团队的自我管理形成良好的团队文化。

  • 协调各方的沟通,包括猪与鸡的沟通。

注意,Scrum过程经理不是真正意义上的经理,不是传统的项目经理,他和团队成员之间不是管理和被管理的关系。Scrum过程经理更像是团队的过程教练,以及团队的“护羊犬”(如果把团队看作是“羊群”的话)。

开发团队是Scrum过程的核心,这是个规模小(5~9人)的跨职能团队。团队应具备软件开发所需要的所有技能:需求分析、设计、编码、测试、技术资料编写等。它的主要责任是通过迭代,不断开发提交对客户有价值的功能特性,同时持续改进提升团队能力,将其潜能最大化。团队的主要工作包括以下几项。

  • 估计产品需求列表中用户故事的复杂度,考虑用户故事的优先级、依赖关系、实现难度等,选择下次迭代的范围,形成迭代需求列表。

  • 遵循团队达成的工程实践共识,完成每个用户故事的需求澄清、设计、编码、评审、测试、资料编写等相关工作,不断提交对客户有价值的需求功能。

  • 不断总结开发过程中的得与失,持续改进个人能力及团队能力。

在第4章讨论敏捷布局时,我还会进一步深入讨论Scrum中的各种角色的选择和要求。

2. Scrum管理框架中的3个文档

在第5章中,我会深入讨论3个文档的使用,这里仅做一个简单介绍。

产品需求列表是Scrum中最重要的文档,它是一个动态的(产品经理可以随时对其进行调整)包含了客户期望的需求的列表清单。大部分敏捷团队使用“用户故事”的形式来表示每一个需求项,产品经理会对它们按价值排序,由高(上)到低(下)。用户故事的颗粒度会有很大差异,主要遵循“近细远粗”的原则:排在最上面的用户故事会被细化,以支持团队近期迭代的实施。而底层故事的颗粒度可以很大,因为前期花精力对其细化很不值得。这些需求后期很可能会变,也有可能根本不需要。因为没有完美的产品,所以产品需求列表永远不可能全。只要一个产品还在被使用,它的需求列表就应该存在。

迭代需求列表则是由团队负责管理,它定义了Scrum团队某次迭代承诺实现的用户故事或任务。在迭代中,它一般是不变的。团队会识别出完成每一个故事所需要完成的任务,通过完成这些任务,提交可提交的工作的软件。每次迭代应该有个主题或目标,Scrum的增量开发是通过不断迭代,完成迭代需求列表中的需求项来实现的。

燃尽图是Scrum中的第三个文档,它主要是用来监控版本及迭代开发进展情况。版本燃尽图显示本次版本未开发的需求项或剩余的工作,而迭代燃尽图则显示一次迭代中未完成的工作。图2-3和图2-4显示了两类燃尽图—版本燃尽图和迭代燃尽图。

0203.tif

图2-3 版本燃尽图

0204.tif

图2-4 迭代燃尽图

燃尽图可以简单清晰地展示迭代完成情况及版本实现情况。

3. Scrum管理框架中的5个会议

在第5章中,我会描述如何开好Scrum中的5个会议,这里只简单介绍一下5个会议的目的。

(1)产品需求列表的细化会议:团队和产品经理一起会细化列在需求列表前面的需求项(用户故事),为近几次(如两次)迭代做好准备。

(2)迭代计划会议:团队从产品需求列表前面被细化的需求项中选择本次迭代要完成的用户故事或任务,形成迭代需求列表。

(3)每日站立会议:这个每日15分钟的例会可以让所有团队成员的工作得到同步,同时及时识别并解决任何影响实现迭代目标的障碍。这是审查(inspect)和调整(adopt)的最小颗粒度。

(4)迭代评审会议:通过演示本次迭代中团队成功完成的需求功能,让产品经理、客户及其他利益相关人加深对产品的理解,调整产品需求列表,逐步识别聚焦到真正对客户有价值的需求特性。这个会议实现了对产品的审查与调整。

(5)迭代回顾会议:这是每次迭代的最后一个活动,团队会在这个会议上对迭代中的问题及好的做法做简单的根因分析,如有必要,会调整团队的Scrum过程及实践。这个会议是对开发过程的审查与调整(改进)。

Scrum中的一个重要时间盒体现在固定的迭代周期(一般2~4周),固定时长的产品需求列表细化会议(2~4小时),固定时长的迭代计划会议(4~8小时),固定时长的每日站立会议(15分钟),固定时长的迭代评审会议(4~6小时)和固定时长的迭代回顾会议(3~6小时)。时间盒是使团队专注、发挥潜能,及早发现问题并做出解决决策的有效手段。

2.2.3 敏捷框架下看Scrum

我们可以很容易在前面描述的敏捷框架下建立以Scrum为核心的开发过程。

愿景阶段可以解读为迭代前的准备,推测阶段可以看作是建立调整版本计划,而探索阶段则对应一次迭代,那么调整阶段就是迭代评审和回顾了。在这个过程中,团队不断优化产品需求列表,同时增量提交实现的功能。

2.2.4 Scrum和极限编程的结合使用

大多数实施Scrum的团队会同时实施一些极限编程(极限编程)的实践,这是因为二者有极好的互补性。软件开发的工程实践是Scrum遗忘的角落,这不是疏忽而是刻意为之,它把如何做(工程实践)留给团队来决定。这个选择同时也带来了开发风险,因为团队有可能会过于追求速度,植入产品的维护及使用隐患。我们把这些隐患称为技术债务,而忽略它们则称之为带病迭代。

由于Scrum迭代周期很短,对开发出软件的充分测试往往是完成迭代目标的瓶颈。极限编程在这方面提出了有效的做法,大大降低了变更成本(这些变更包括需求、设计和编码)。在实施Scrum时,建立能支持持续集成等极限编程实践的环境及能力,是成功实施Scrum的重要保证。

在下一章我会详细介绍极限编程的原则及重要实践。

2.3 Scrum是一个实现敏捷价值及原则的开发管理架构

不难看出Scrum的实践(从20世纪90年代初开始)是敏捷宣言及原则的一个重要来源。真正合理使用Scrum,需要团队真正理解敏捷原则、实践、Scrum架构,同时用这些原则、实践、架构解决团队在开发软件中遇到的问题。Scrum是一个实现敏捷价值、体现敏捷原则的开发模式。

2.3.1 Scrum让敏捷价值的实现变得自然

1. Scrum让团队和客户的合作沟通变得简单

Scrum从传统的任务驱动管理转换为需求特性驱动管理,这个转换带来的最大好处之一是让团队关注的东西和客户关注东西高度一致。客户并不关心团队是如何实现需求功能的,一般也没有能力判断团队的开发及管理活动的合理性,他们关注的是团队实现的需求功能:哪些能实现,哪些不能实现,什么时间能提交,是否能调整需求(加、减、改)。

Scrum过程设置了一个专门的角色(产品经理)来和客户沟通,他同时又是客户和团队的沟通桥梁。这样客户有一个明确的渠道随时将他们的想法转达给团队,同时有一个既理解他们所需产品价值又了解开发团队能力的人帮助他们做产品规划。

由于每次迭代的周期都很短(一般不超过4周),哪怕是两年的项目,客户也可以不断看到团队实现的需求功能,给出需求优化的反馈。实现的需求真正变成了和客户沟通的载体,客户可以在整个开发过程中不断用自己熟悉的东西和团队进行沟通。

2. Scrum大大降低了变更成本

新的需求可以随时加到产品需求列表中,而迭代需求列表在迭代中一般是稳定不变的,这样需求变更造成的成本会比传统模式少很多。而短的迭代周期也降低了技术变更(如设计)造成的返工,以及需求不明确带来的返工。高频率的审查(每日例会、迭代评审和回顾会)也缩短了缺陷及问题植入和发现的距离,从而降低了质量成本。当然前提是团队真正掌握了Scrum管理实践,让改进变成团队常态化的活动。

3.工作的软件是Scrum中最重要的进展度量

每次迭代最重要的产出物是工作的软件,在迭代评审会上,我们只会演示达到“完成”(Done)标准的程序。其他工程管理文档都是用来支持团队开发出工作的软件。增量开发也就是代码库的不断扩张。

2.3.2 Scrum是敏捷原则的具体体现

让我们看一下Scrum是如何体现敏捷的12条原则的。

(1)产品需求列表中的优先级及每次迭代后持续提交工作软件体现了第一敏捷原则。

(2)产品需求列表的随时更新保证了第二原则的实现。

(3)1~4周的迭代周期保证了第三原则的实现。

(4)Scrum的跨职能团队及每日15分钟的站立会议实现第四原则。

(5)Scrum中的自我管理原则也是敏捷的第五原则。

(6)5~9人的小团队,白板的使用以及面对面的沟通等Scrum实践保证第六原则的实现。

(7)Scrum对工作的软件的关注实现了敏捷第七原则。

(8)时间盒的概念、迭代速率(Velocity)的使用支持第八原则的实现。

(9)Scrum要求对产品需求列表中每一个用户故事都定义一个完成(Done)标准,这对第九原则的实现有很好的推动。Scrum对第九原则实现的保证不是很强,这也是很多Scrum团队同时引入一些极限编程实践的原因。

(10)Scrum为实施敏捷第十原则提供了一个很好的框架,不断地审查和调整,变更成本的降低,都为尽量只做正好够的东西(just enough)以及在恰当时间(just in time)做决策提供了有力的支持。

(11)Scrum将“如何做”完全放在团队的手中,这是对敏捷第十一原则的诠释。对团队自律的要求会逐步将一群人变成一个真正的团队。

(12)Scrum的回顾会议就是第十二原则的体现。

如果能在企业级为敏捷实施提供有效的支持,形成一个精益(Lean)文化,如果团队能够结合实际,建立一个合理的Scrum过程,并不断完善这个过程,那么这样的Scrum是新的项目管理铁三角的绝配。这样的Scrum也能让团队用小的代价实现高价值产品需求特性。

一个团队的两个故事

故事1:团队A的第一个故事

Team A是国内一家著名IT公司的一个开发团队,为了提高开发效率,Team A决定在下一个项目中引入Scrum。公司任命贾工担任团队的Scrum过程经理,同时也是项目经理。贾工是个很有经验的项目经理,公司派他参加过一些外部Scrum培训,他自己也上网了解了Scrum的很多实践。贾工对每日例会印象深刻,觉得很有道理,他认为每日例会是Scrum的核心活动。

新项目的客户要求团队18月后提交产品,公司为了争取这个单子,在没有做必要可行性分析的情况下,做出了进度承诺。贾工十几年的管理经验都是在传统瀑布架构下积累的,他在做计划时还是摆脱不了瀑布思维。他把项目分成了下列几个阶段,阶段中间有些重叠。

  • 需求分析阶段:目标是梳理清楚客户需求,并将功能及性能需求项记录在软件需求规格说明书中。

  • 设计阶段:目标是完成概要及详细设计,并产生对应的设计文档。

  • 编码阶段:目标是依据设计完成编码工作。

  • 测试阶段:目标是对完成的代码进行测试,发现缺陷并修复回归。

  • 发布阶段:目标是通过客户验收。

贾工依据Scrum的实践,引入了每日例会和任务管理白板。但这些例会,不同阶段有不同人员参加,如在需求阶段只有相关需求人员参加,设计阶段只有相关设计人员参加。贾工觉得很多其他Scrum实践在本项目里很难使用。例如他觉得有了需求规格说明书,就不需要再做一个产品需求列表了。很快到了年底,离发布只有6个月了,管理层和客户要求贾工对项目进展状况做个分析,并回答他们最关心的问题:团队是否能按时在6个月后提交满足客户要求的工作软件?

贾工报上来的结论让管理层十分失望,如果按目前进展情况估计,完成合同中所有需求功能,至少还需要18个月。也就是说,项目需要延期一年。

管理层不能接受这个答案,要求贾工必须按时提交满足客户要求的工作软件。和团队沟通后,贾工正式向公司提出了辞职,另谋出路了。

 

故事2:团队A的第二个故事

公司决定为团队A请一位业界口碑很好的敏捷教练郑博士做新的过程经理,希望他能够挽救这个项目。在给管理层一个新的计划之前,郑博士首先对项目做了诊断,识别出下列几个问题。

  • 团队花了很大精力整理出了一份200多页的需求规格说明书,但不能起到产品需求列表的作用—优先级不清晰,变更成本很高。团队只能开发完需求规格说明书中的所有功能后才能提交产品。

  • 团队内部缺乏信任,职责不明,承诺很随意。

  • 团队成员会随意被管理层分派其他所谓更重要的任务。

  • 测试及构建环境不能有效支持高效开发。

  • 估算随意且无依据。

郑博士同时和团队一起也做了下列几件事。

  • 建立产品需求列表。

  • 定义了完成标准:可发布是完成标准的依据。同时把测试人员安排为Scrum团队成员。

  • 依据当前的需求列表中的故事,估计用户故事点。需求列表中含尚未开始编码的故事及已完成编码但尚未测试的故事。前者的规模是180点,后者是70点,总计250点。

团队接下来按Scrum过程完成了两个周期为两周的迭代:第一次迭代,团队计划完成30故事点,但实际完成9个点。第二次迭代,团队在迭代需求列表放入了25个故事点,实际完成了10个故事点。

根据这些信息,郑博士向管理层提出了新的计划:产品需求列表一共有250故事点,按每次迭代完成10个故事点算(团队速率),团队还需要25次迭代。每次迭代的周期是2个星期,郑博士代表团队承诺一年后完成项目。这就意味着项目要延期6个月。

和客户沟通后,管理层否决了这个计划,还是坚持按期提交。郑博士代表团队同意按合同执行,但要求客户和管理层同意团队的两个要求。

  • 缩小需求功能范围:将非必要及价值低的用户故事从产品需求列表中删去。

  • 分两次发布:在合同要求的时间点,发布产品主要功能;3个月后发布剩余功能。

管理层和客户同意了团队的要求,并据此重新调整了合同。郑博士同时也向管理层提出一些期望。

  • 相信团队会主动把事情做好,不要给团队施加不必要的压力,提出达不到的要求。

  • 对测试及集成构建环境做必要的投入。

  • 在迭代开发过程中,尽可能不要抽调团队成员做其他事情。

  • 给团队更多的鼓励、支持。

郑博士在团队建设方面也做了很多工作,重点解决团队的自律、动力、相互配合等问题,使团队真正成为一个拳头而不是5个分开的指头。

经过6次迭代,团队的速率从10达到了近30。在项目启动后的第十八个月,提交的软件通过了客户验收。3个月后团队成功提交了剩余功能。

团队A的两个故事纳入了公司敏捷实施培训教材。

目录

相关技术

推荐用户