敏捷方法
2001年2月,在美国的犹他州,17位“无政府主义者”共同发表了《敏捷软件开发宣言》,在宣言中指出:
● 尽早地、持续地向客户交付有价值的软件对开发人员来说是最重要的。
● 拥抱变化,即使在开发的后期。敏捷过程能够驾驭变化,保持客户的竞争力。
● 经常交付可工作的软件,从几周到几个月,时间范围越小越好。
● 在整个项目中,业务人员和开发者紧密合作。
● 围绕士气高昂的团队进行开发,为团队成员提供适宜的环境,满足他们的需要,并给予足够的信任。
● 在团队中,最有效率的、也是效果最好的沟通方式是面对面地交流。
● 可以工作的软件是进度首要的度量方式。
● 可持续地开发。投资人、开发团队和用户应该保持固定的节奏。
● 不断追求优秀的技术和良好的设计有助于提高敏捷性。
● 要简单,尽可能减少工作量。减少工作量的艺术是非常重要的。
● 最好的架构、需求和设计都来自于一个自我组织的团队。
● 团队要定期地总结如何能够更有效率,然后相应地自我调整。
至此,敏捷软件联盟建立起来,敏捷软件开发方法进入了大发展的时代。这份宣言也就是敏捷方法的灯塔,所有的敏捷方法都在向这个方向努力。目前已形成多种敏捷方法,其中XP传播最为广泛,为此,本节主要介绍XP,其次简单介绍另外几种很有特色的开发模型。
一、极限编程
XP方法可以说是敏捷联盟中最鲜艳的一面旗帜,也是相对来说最成熟的一种。XP方法的雏形最初形成于1996—1999年间,Kent Beck、Ward Cunningham、Ron Jeffery夫妇在开发C3项目(Chrysler Comprehensive Compensation)的实践中总结出了XP的基本元素。在此之后,Kent Beck 和他的一些好朋友们一起在实践中完善提高,终于形成了极限编程方法。
XP是一种轻量(敏捷)、高效、低风险、柔性、可预测、科学而且充满乐趣的软件开发方式。与其他方法论相比,其最大的不同在于:
(1)在更短的周期内,更早地提供具体、持续的反馈信息。
(2)迭代地进行计划编制,首先在最开始迅速生成一个总体计划,然后在整个项目开发过程中不断地发展它。
(3)依赖于自动测试程序来监控开发进度,并及早地捕获缺陷。
(4)依赖于口头交流、测试和源程序进行沟通。
(5)倡导持续的、演化式的设计。
(6)依赖于开发团队内部的紧密协作。
(7)尽可能达到程序员短期利益和项目长期利益的平衡。
XP 由价值观、原则、实践和行为四个部分组成,它们彼此相互依赖、关联,并通过行为贯穿于整个生命周期。
1.四大价值观
XP的核心是其总结的沟通、简单、反馈、勇气四大价值观,它们是XP的基础,也是XP的灵魂。
(1)沟通。通常,程序员给人留下的印象就是“内向、不善言谈”,项目中的许多问题就出在这些缺乏沟通的开发人员身上。由于某个程序员做出了一个设计决定,但是却不能够及时地通知团队中的其他成员,结果使得团队在协作与配合上出现很多麻烦。而在传统的开发方法中,并不在意这种口头沟通不畅的问题,而是希望借助于完善的流程和面面俱到的文档、报表、计划来替代,但是,这又引入了效率不高的新问题。
XP 方法认为,如果小组成员之间无法做到持续的、无间断的交流,那么协作就无从谈起。从这个角度来看,通过文档、报表等人工制品进行交流,具有很大的局限性。因此,XP 组合了诸如结对编程这样的最佳实践,鼓励大家进行口头交流、通过交流解决问题,提高效率。
(2)简单。XP 方法在工作中秉承“够用即好”的思路,也就是尽量地简单化,只要今天够用就行,不考虑明天会出现的新问题。这一点看上去十分容易,但要真正做到保持简单的工作其实是很难的,因为在传统的开发方法中,都要求开发人员对未来做一些预先规划,以便对今后可能发生的变化预留一些扩展空间。
沟通和简单之间还有一种相当微妙的互相支持关系。一方面,团队成员之间沟通得越多,就越容易明白哪些工作需要做,哪些工作不需要做;另一方面,系统越简单,需要沟通的内容也就越少,沟通也将更加全面。
(3)反馈。是什么原因使得客户、管理层这么不理解开发团队?究其症结,就是开发的过程中缺乏必要的反馈。在很多项目中,当开发团队经历过了需求分析阶段之后,在一个相当长的时间段中,是没有任何反馈信息的。整个开发过程对于客户和管理层而言就像一个黑盒子,进度完全看不到。而且,在项目开发过程中,这样的现象不仅出现在开发团队与客户、管理层之间,还包括在开发团队内部。因此,开发团队需要更加注重反馈。反馈对于任何软件项目的成功都是至关重要的,而在XP方法论中则更进一步,通过持续、明确的反馈来暴露软件状态的问题。
反馈与沟通有着良好的配合,及时和良好的反馈有助于沟通。而简单的系统,更有利于测试和反馈。
(4)勇气。在应用XP方法时,每时每刻都在应对变化:由于沟通良好,会有更多需求变更的机会;由于时刻保持系统的简单,新的变化会带来一些重新开发的需要;由于反馈及时,会有更多中间打断思路的新需求。总之,这一切使得开发团队处于变化之中,因此,这时就需要有勇气来面对快速开发,面对可能的重新开发。勇气可以来源于沟通,因为它使得高风险、高回报的试验成为可能;勇气可以来源于简单,因为面对简单的系统,更容易鼓起勇气;勇气可以来源于反馈,因为可以及时获得每一步前进的状态(自动测试),会让人更勇于重构代码。
2.十二个最佳实践
在XP中,集成了12个最佳实践,有趣的是,它们没有一个是创新的概念,大多数概念和编程一样老。其主要的创新点在于提供一种良好的思路将这些最佳实践结合在一起,并且确保尽可能彻底地执行,使得它们能够在最大程度上互相支持。
(1)计划游戏。计划游戏的主要思想就是先快速地制定一份概要的计划,然后,随着项目细节的不断清晰,再逐步完善这份计划。计划游戏产生的结果是一套用户故事及后续的一两次迭代的概要计划。
(2)小型发布。XP 方法秉承的是“持续集成、小步快走”的哲学思维,也就是说每一次发布的版本应该尽可能地小,当然前提条件是每个版本有足够的商业价值,值得发布。由于小型发布可以使得集成更频繁,客户获得的中间结果越频繁,反馈也就越频繁,客户就能够实时地了解项目的进展情况,从而提出更多的意见,以便在下一次迭代中计划进去,以实现更高的客户满意度。
(3)隐喻。相对而言,隐喻比较令人费解。根据词典中的解释是:“一种语言的表达手段,它用来暗示字面意义不相似的事物之间的相似之处”。隐喻常用于四个方面:寻求共识、发明共享语汇、创新的武器、描述架构。如果能够找到合适的隐喻是十分快乐的,但并不是每一种情况都可以找到恰当的隐喻,因此,没有必要去强求,而是顺其自然。
(4)简单设计。强调简单的价值观,引出了简单性假设原则,落到实处就是“简单设计”实践。这个实践看上去似乎很容易理解,但却又经常被误解,许多批评者就指责 XP忽略设计是不正确的。其实,XP 的简单设计实践并不是要忽略设计,而是认为设计不应该在编码之前一次性完成,因为那样只能建立在“情况不会发生变化”或者“我们可以预见所有的变化”之类的谎言的基础上。
(5)测试先行。对于有些团队而言,有时候程序员会以“开发工作太紧张”为理由,继而忽略测试工作。这样,就导致了一个恶性循环,越是没空编写测试程序,代码的效率与质量越差,花在找缺陷、解决缺陷的时间也越来越多,实际产能大大降低。由于产能降低,因此时间更紧张,压力就更大。
(6)重构。重构是一种对代码进行改进而不影响功能实现的技术,XP 需要开发人员在“闻到代码的坏味道”时,就有重构代码的勇气。重构的目的是降低变化引发的风险、使得代码优化更加容易。
(7)结对编程。从20世纪60年代开始,就有类似的实践在进行,长年以来的研究结果给出的结论是,结对编程的效率反而比单独编程更高。一开始虽然会牺牲一些速度,但慢慢地,开发速度会逐渐加快。究其原因,主要是结对编程大大降低了沟通的成本,提高了工作的质量。结对编程技术被誉于XP保证工作质量、强调人文主义的一个最典型的实践,应用得当还能够使开发团队协作更加顺畅、知识交流与共享更加频繁、团队稳定性也会更加牢固。
(8)集体代码所有制。由于XP方法鼓励团队进行结对编程,而且认为结对编程的组合应该动态地搭配,根据任务的不同、专业技能的不同进行最优组合。因此,每一个人都会遇到不同的代码,代码的所有制就不再适合于私有,因为那样会给修改工作带来巨大的不便。所谓集体代码所有制,就是团队中的每个成员都拥有对代码进行改进的权利,每个人都拥有全部代码,也都需要对全部代码负责。同时,XP 强调代码是谁破坏的(修改后出现问题),就应该由谁来修复。集体代码所有制是XP与其他敏捷方法的一个较大不同,也是从另一个侧面体现了XP中蕴含的很深厚的编码情节。
(9)持续集成。在前面谈到小型发布、重构、结对编程、集体代码所有制等最佳实践的时候,多次提到“持续集成”,可以说持续集成是这些最佳实践的基本支撑条件。
(10)每周工作40小时。这是最让开发人员开心、管理者反对的一个最佳实践了,加班、再加班早已成为开发人员的家常便饭,也是管理者最常使用的一种策略。而XP方法认为,加班最终会扼杀团队的积极性,最终导致项目的失败,这也充分体现了XP方法关注人的因素比关注过程的因素更多一些。不过,有一点是需要解释的,“每周工作 40小时”中的“40”不是一个绝对数,它所代表的意思是团队应该保证按照“正常的时间”进行工作。
(11)现场客户。为了保证开发出来的结果与客户的预想接近,XP方法认为最重要的是需要将客户请到开发现场。就像计划游戏中提到过的,在XP项目中,应该时刻保证客户负责业务决策,开发团队负责技术决策。因此,在项目中有客户在现场明确用户故事,并做出相应的业务决策,对于XP项目而言有着十分重要的意义。
(12)编码标准。拥有编码标准可以避免团队在一些与开发进度无关的细枝末节问题上发生争论,而且会给重构、结对编程带来很大的麻烦。不过,XP 方法的编码标准的目的不是创建一个事无巨细的规则列表,而是要能够提供一个确保代码清晰,便于交流的指导方针。
有句经典名言“1+1﹥2”最适合表达XP的观点,Kent Beck认为,XP方法的最大价值在于,在项目中融会贯通地运用这 12 个最佳实践,而非单独使用。当然,可以使用其中的一些实践,但这并不意味着就应用了XP方法。XP方法真正能够发挥其效能,就必须完整地运用12个实践。
二、Scrum
Scrum是一个用于开发和维持复杂产品的框架 ,是一个增量的、迭代的开发过程。在这个框架中,整个开发过程由若干个短的迭代周期组成,一个短的迭代周期称为一个Sprint,每个Sprint的建议长度是2到4周(互联网产品研发可以使用1周的Sprint)。在Scrum中,使用产品Backlog来管理产品的需求,产品Backlog是一个按照商业价值排序的需求列表,列表条目的体现形式通常为用户故事。Scrum团队总是先开发对客户具有较高价值的需求。在Sprint中,Scrum团队从产品Backlog中挑选最高优先级的需求进行开发。挑选的需求在 Sprint 计划会议上经过讨论、分析和估算得到相应的任务列表,我们称它为Sprint backlog。在每个迭代结束时,Scrum团队将递交潜在可交付的产品增量。 Scrum起源于软件开发项目,但它适用于任何复杂的或是创新性的项目。Scrum的基本流程如图所示。
1.Scrum的五个活动
Scrum主要包括:产品待办事项列表梳理、Sprint计划会议、每日Scrum会议、Sprint评审会议、Sprint回顾会议等五个活动。
(1)产品待办事项列表梳理
产品待办事项通常会很大,也很宽泛,而且想法会变来变去、优先级也会变化,所以产品待办事项列表梳理是一个始终贯穿整个Scrum项目的活动。该活动包含但不限于以下的内容:保持产品待办事项列表有序、把看起来不再重要的事项移除或者降级、增加或提升涌现出来的或变得更重要的事项、将事项分解成更小的事项、将事项归并为更大的事项、对事项进行估算。
产品待办事项列表梳理的一个最大好处是为即将到来的几个Sprint做准备。为此,梳理时会特别关注那些即将被实现的事项。需要考虑不少因素,这包括但不限于以下的内容:
理想情况下,下一个 Sprint 的备选事项都应该提升“商业价值”。开发团队需要能够在一个Sprint内完成每一个事项。每个人都需要清楚预期产出是什么。
产品开发决定了,有可能需要其他的技能和输入。因此,产品待办事项列表梳理最好是所有团队成员都参与的活动,而不单单是产品负责人。
(2)Sprint计划会议
每个Sprint都以Sprint计划会议作为开始,这是一个固定时长的会议,在这个会议中,Scrum团队共同选择和理解在即将到来的Sprint中要完成的工作。
整个团队都要参加 Sprint 计划会议。针对排好序的产品待办事项列表(Product Backlog),产品负责人和开发团队成员讨论每个事项,并对该事项达成共识,包括根据当前的“完成的定义”,为了完成该事项所需要完成的所有事情。所有的 Scrum 会议都是限定时长的。Sprint计划会议推荐时长是Sprint中的每周对应两小时或者更少(例如,一个Sprint包含2个星期,则Sprint计划会议时长应为4个小时或者更少)。因为会议是限制时长的,Sprint 计划会议的成功十分依赖于产品待办事项列表的质量。这就是产品待办事项列表梳理十分重要的原因。
在Scrum中,Sprint计划会议有两部分:
■ 决定在Sprint中需要完成哪些工作
■ 决定这些工作如何完成
第一部分:需要完成哪些工作?
在会议的第一部分,产品负责人向开发团队介绍排好序的产品待办事项,整个Scrum团队共同理解这些工作。
Sprint 中需要完成的产品待办事项数目完全由开发团队决定。为了决定做多少,开发团队需要考虑当前产品增量的状态,团队过去的工作情况,团队当前的生产能力,以及排好序的产品待办事项列表。做多少工作只能由开发团队决定。产品负责人或任何其他人,都不能给开发 团队强加更多的工作量。
通常Sprint都有个目标,称作Sprint目标。这将十分有效地帮助大家更加专注于需要完成的工作的本质,而不必花太多精力去关注那些对于我们需要完成的工作并不重要的小细节。
第二部分:如何完成工作?
在会议的第二部分里,开发团队需要根据当前的“完成的定义”一起决定如何实现下一个产品增量。他们进行足够的设计和计划,从而有信心可以在Sprint中完成所有工作。前几天的工作会被分解成小的单元,每个工作单元不超过一天。之后要完成的工作可以稍大些,以后再对它们进行分解。
决定如何完成工作是开发团队的职责,决定做什么则是产品负责人的职责。
在计划会议的第二部分,产品负责人可以继续留下来回答问题,以及澄清一些误解。不管怎样,团队应该很容易找到产品负责人。
Sprint计划会议的产出。Sprint计划会议最终需要Scrum团队对Sprint需要完成工作的数量和复杂度达成共识,并预期在一个合理的条件范围内完成它们。开发团队预测并共同承诺他们要完成的工作量。总而言之:在Sprint计划会议中,开发团队和产品负责人一起考虑并讨论产品待办事项,确保他们对这些事项的理解,选择一些他们预测能完成的事项,创建足够详细的计划来确保他们能够完成这些事项。
最终产生的待办事项列表就是“Sprint待办事项列表(Sprint Backlog)”。
(3)每日Scrum会议
开发团队是自组织的。开发团队通过每日Scrum会议来确认他们仍然可以实现Sprint的目标。这个会议每天在同样的时间和同样的地点召开。每一个开发团队成员需要提供以下三点信息:
从上一个每日Scrum到现在,我完成了什么;从现在到下一个每日Scrum,我计划完成什么;有什么阻碍了我的进展。
每日Scrum中可能有简要的问题澄清和回答,但是不应该有任何话题的讨论。通常,许多团队会在每日Scrum之后马上开会处理他们遇到的任何问题。
每日Scrum既不是向管理层汇报,也不是向产品负责人或者ScrumMaster汇报。它是一个开发团队内部的沟通会议,来保证他们对现状有一致的了解。只有Scrum团队的成员,包括ScrumMaster和产品负责人,可以在会议中发言。其他感兴趣的人可以来旁听。在必要时,开发团队会基于会议中的发现重新组织他们的工作来完成Sprint的目标。
每日Scrum是Scrum的一个关键组成部分,它可以带来透明性,信任和更好的绩效。它能帮助快速发现问题,并促进团队的自组织和自立。所有Scrum会议都是限定时长的。每日Scrum通常不超过15分钟。
(4)Sprint评审会议
Sprint结束时,Scrum团队和相关人员一起评审Sprint的产出。Sprint评审会议的推荐时长是Sprint中的每一周对应一个小时(例如,一个Sprint包含2个星期,则Sprint评审会议时长为2个小时)。
讨论围绕着 Sprint 中完成的产品增量。由于 Sprint 的产出会涉及一些人的“利益”,因此一个明智的做法是邀请他们参加这个会议,这会很有帮助。这个会议是个非正式的会议,帮助大家了解我们目前进展到哪里,并一起讨论我们下一步如何推进。每个人都可以在Sprint评审会议上发表意见。当然,产品负责人会对未来做出最终的决定,并适当地调整产品待办事项列表Product Backlog。
团队会找到他们自己的方式来开Sprint评审会议。通常会演示产品增量,整个小组也会经常讨论他们在Sprint中观察到了什么、有哪些新的产品想法出现。他们还会讨论产品待办事项列表的状态、可能的完成日期以及在这些日期前能完成什么。
Sprint评审会议向每个人展示了当前产品增量的概况。因此,通常都会在Sprint评审会议中调整产品待办事项列表。
(5)Sprint回顾会议
在每个Sprint结束后,Scrum团队会聚在一起开Sprint回顾会议,目的是回顾一下团队在流程人际关系以及工具方面做得如何。团队识别出哪些做得好,哪些做得不好,并找出潜在的改进事项,为将来的改进制定计划。Sprint回顾会议的推荐时长是Sprint中的每一周对应一个小时(例如,一个Sprint包含2个星期,则Sprint回顾会议时长为2个小时)。
Scrum团队总是在Scrum的框架内,改进他们自己的流程。
2.Scrum的5大价值观
Scrum的5大价值观为:
承诺—愿意对目标做出承诺。
专注—把你的心思和能力都用到你承诺的工作上去。
开放—Scrum把项目中的一切开放给每个人看。
尊重—每个人都有他独特的背景和经验。
三、 特征驱动开发
FDD方法来自于一个大型的新加坡银行项目。FDD的创立者Jeff De Luca和Peter Coad分别是这个项目的项目经理和首席架构设计师。在Jeff和Peter接手项目时,客户已经经历了一次项目的失败,从用户到高层都对这个项目持怀疑的态度,项目组士气低落。随后,Jeff和Peter采用了特征驱动、彩色建模等方法,最终获得了巨大成功。
FDD是也是一个迭代的开发模型。FDD 的每一步都强调质量,不断地交付可运行的软件,并以很小的开发提供精确的项目进度报告和状态信息。同敏捷方法一样,FDD弱化了过程在软件开发中的地位。虽然 FDD 中也定义了开发的过程,不过一个几页纸就能完全描述的过程深受开发者的喜爱。
1.FDD角色定义
FDD认为,有效的软件开发不可缺少的三个要素是:人、过程和技术。软件开发不能没有过程,也不能没有技术,但软件开发中最重要的是人。个人的生产率和人的技能将会决定项目的成败。为了让项目团队能够紧密地工作在一起,FDD定义了6种关键的项目角色:
(1)项目经理。项目经理是开发的组织者,但项目经理不是开发的主宰。对于项目团队来说,项目经理应该是团队的保护屏障。他将同团队外界(如高层领导、人事甚至写字楼的物业管理员)进行沟通,努力为团队提供一个适宜的开发环境。
(2)首席架构设计师。不难理解,首席架构设计师负责系统架构的设计。
(3)开发经理。开发经理负责团队日常的开发,解决开发中出现的技术问题与资源冲突。
(4)主程序员。主程序员将带领一个小组完成特征的详细设计和构建的工作,一般要求主程序员具有一定的工作经验,并能够带动小组的工作。
(5)程序员。若干个程序员在主程序员的带领下形成一个开发小组,按照特征开发计划完成开发。
(6)领域专家。领域专家是对业务领域精通的人,一般由客户、系统分析员等担当。领域专家作为关键的项目角色正是敏捷宣言中“业务人员同开发人员紧密合作”的体现。
根据项目规模的大小,有些角色是可以重复的。例如在一个小规模项目中,项目经理自身的能力很强,他就可以同时担当项目经理、首席架构设计师和开发经理的角色。
2.核心过程
FDD共有5个核心过程,如图所示。
(1)开发整体对象模型。开发整体对象模型也就是业务建模的阶段。不过 FDD 强调的是系统地完整地面向对象建模,这种做法有助于把握整个系统,而不仅仅关注系统中的若干个点。在这一阶段,领域专家和首席架构设计师相互配合,完成整体对象模型。
(2)构造特征列表。完成系统建模后,需要构造一个完整的特征列表。所谓特征指的是一个小的、对客户有价值的功能。采用动作、结果和目标来描述特征,特征的粒度最好可以在两周之内实现。在这一阶段中,可以整理出系统的需求。
(3)计划特征开发。很少看到有哪个软件在开发过程中明确包含计划过程,其实任何一个软件项目都必须有计划——无论是重载方法还是敏捷方法。在这一阶段中,项目经理根据构造出的特征列表、特征间的依赖关系进行计划,安排开发任务。
(4)特征设计。在这一阶段,主程序员将带领特征小组对特征进行详细设计,为后面的构建做准备。
(5)特征构建。特征构建和特征设计这两个阶段合并起来可以看做特征的实现阶段,这两个阶段反复地迭代,直到完成全部的开发。
3.最佳实践
组成 FDD 的最佳实践包括:领域对象建模、根据特征进行开发、类的个体所有、组成特征小组、审查、定期构造、配置管理、结果的可见性。
其中,最有特色的莫过于类的个体所有。几乎所有的开发模型都是代码共有,程序员们负责开发系统中的全部代码,并通过配置管理和变更控制来保持代码的一致性。在FDD中,将类分配给特定的任何小组,分配给A成员的代码将全部由A来维护,除A外的角色都不能修改它,只能使用它。这样做当然有它的优点:个人对所分配的类很容易保持概念的完整性;开发类代码的人肯定是最熟悉这个类的主人;而对这个类的支配感会促使开发人员产生自豪感,从而更出色地完成任务。不过 FDD 也提到了类个体所有的缺陷:项目中的依赖关系增强、当A需要B修改他自己的类时,必须等待B完成修改才能使用;类的个体所有增加了员工离职的损失。面对这些优点和缺陷,显然 FDD 认为类的个体所有对系统开发更有帮助。
除类的个体所有外,审查也是 FDD 中很具特色的一项实践。不少人都认为审查是非常严格的软件过程所特有的,因为进行审查不但要花费不少的人力和时间,对审查者本身的素质也有要求。然而在 FDD 中,明确地将审查作为一项最佳实践提出。审查是一种很有效的发现缺陷的手段,但经常被忽视,国内的软件组织中很少有严格审查制度保证软件质量。有效的审查可以发现很多潜在的问题,而这些问题往往是无法通过测试发现的,例如建模、需求和设计期的缺陷。这些潜在的缺陷大多要到系统测试甚至发布后才能发现,修正这些缺陷的代价是很大的。