敏捷软件开发(珍藏版)
上QQ阅读APP看书,第一时间看更新

第1章 敏捷实践

“教堂屋顶上的风标,即使是由钢铁制成,如果不懂得顺势而为,也很快会被暴风摧毁。”

—海涅(1)

我们许多人都经历过因为缺乏实践指导而导致的项目梦魇。有效实践的缺失会带来不确定性、重复的错误以及徒劳无功。客户失望于延期的进度、增长的预算和糟糕的质量;开发者也感到沮丧,因为他们用的时间更长却写出了质量更低劣的软件。

一旦经历这样的惨败,人们就会害怕重蹈覆辙。这种恐惧感促使我们创造出一种过程,以此来约束自己的活动并要求特定的输出或产出物(artifact)。我们根据过去的经验制定出这些约束和产出,挑选出之前项目中看似工作得还不错的方法。我们希望这些方法能再次奏效,从而消除自己内心的恐惧。

不过,项目没有简单到只用一些约束和产出物就可以避免错误发生。随着错误的持续产生,我们在诊断之后又增加了更多的约束和产出物要求,目的是防止将来犯同样的错误。在经历过许多项目后,这些压得我们喘不过气来的厚重过程反过来严重影响了我们完成工作的能力。

厚重的过程会产生事与愿违的结果,它会在一定程度上拖慢团队的进度,拖垮项目的预算,也会降低团队的响应力,让软件质量变得不堪。不幸的是,这又会加剧很多团队确信他们需要更多过程的认知。因此,在失控的恶性膨胀下,团队过程的厚重程度愈演愈烈。

失控的恶性膨胀很好地描述了2000年前后很多软件公司的状况。尽管还有不少团队在工作中并没有使用过程方法,但是很多公司都逐渐采纳了大而厚重的过程方法,大公司更是如此。(参见附录C)

敏捷联盟

2001年初,由于观察到很多公司的软件团队被困在不断增长的过程方法的泥泞里,一群行业专家挺身而出,拟定了一系列可以让团队快速响应变化的价值观和原则。他们成立了敏捷联盟。在随后的几个月里,共同创造出一份价值陈述。这便是《敏捷宣言》(agilealliance.org)。

敏捷宣言

敏捷软件开发宣言

我们正在这样做以及帮助其他人这样做来揭示更好的开发软件方法。借由这项工作,我们开始重视

个体交互 优先于 过程和工具

可以工作的软件 优先于 面面俱到的文档

客户合作 优先于 合同谈判

响应变化 优先于 遵循计划

尽管右项有其价值,但我们更加重视左项的价值。

Kent Beck  Mike Beedle  Arie van Bennekum Alistair Cockburn

Ward Cunningham Martin Fowler James Grenning Jim Highsmith

Andrew Hunt  Ron Jeffries Jon Kern Brian Marick

Robert C. Martin Steve Mellor  Ken Schwaber   Jeff Sutherland

Dave Thomas

个体交互优先于过程和工具

人是项目成功的最关键因素。如果缺少优秀的人,即使是很好的过程方法,也无法避免项目失败,反之,不好的过程方法倒是可以让最优秀的人变得低效。一群优秀的人如果无法作为一个团队运作,也会导致项目遭受巨大的失败。

优秀的人未必非得是顶尖的程序员,他们可以是处于平均水平的程序员,但可以和其他人合作无间。默契的合作、沟通和交流比单纯的编程才能重要得多。一群沟通顺畅的、处于平均水平的程序员比一群无法合作的明星程序员更有可能获得成功。

合适的工具对工作大有裨益。编译器、IDE和源代码控制这些工具,对团队而言非常重要。不过,工具的重要性也可能被过分强调了。笨重的工具和缺乏工具,两者的结果一样坏。

我的建议是从最简单的开始。不要预先假设手头上的工具无法支撑需求,除非在尝试后发现确实如此。别去购买先进又昂贵的源代码版本控制工具,在你能证明无法支撑需求之前,先找个免费的用着。别去购买最佳CASE工具的团队证书(license),在你能给出充足的需要理由之前,先用白板和图纸。在使用顶级的数据库之前,先用没有相对结构的代替。也不要假设更大更好的工具就能自动帮你做好事情。通常情况下,用它们,弊大于利。

记住,团队建设比环境搭建更重要。很多团队和管理者都搞错了,以为搭建好的环境,团队就能自动凝聚到一起。应该首先建设团队,然后让他们自己从基本需求出发,去配置环境。

可以工作的软件优先于面面俱到的文档

没有文档的软件就是一场灾难。代码不是用来沟通系统基本原理和结构的理想介质。相反,团队需要提供可读的文档,这些文档描述了系统和设计决策的基本原理。

不过,太多的文档比没有文档更可怕。庞大的软件文档需要花很多时间去写,还需要更多的时间保持和代码的同步。如果无法保持同步,它们就会变成庞大且费解的谎言,成为误解的罪魁祸首。

让团队编写和维护基本原理与结构的文档通常都是有益的,但是这些文档需要短小精悍,言简意赅。所谓短,说的是最多只有12到24页;所谓精,则是说它应该描述整体设计的基本原理,只包含系统中高层次的结构。

如果团队只有简短的基本原理和结构的文档,那么如何在工作中培训新人呢?答案是和他们一起工作。通过坐在旁边亲自辅导来传递知识,通过紧密的培训和交互来使他们成为团队的一份子。

代码和团队是给新人传递信息的最佳文档。代码不会说谎,虽然从代码中提取基本原理和意图比较困难,但是代码却是无二义性信息的来源。团队成员的大脑里关于系统的路线图无时无刻不在改变。传递这样的路线图,除了人与人之间的交互,没有其他更快、更高效的方式了。

很多团队迷失在追求文档而非软件上。这通常是个巨大的错误。有条简单的规则,称为“文档的马丁第一原则”,意在防止此类错误发生:

除非文档紧急且重要,否则不要写。

客户合作优先于合同谈判

软件无法像商品一样订购。写一份关于软件的描述,然后让其他人在固定的时间内以固定的价格开发完成,这种做法是不可行的。尝试这种做法的软件项目频繁失败,有时候,这种失败是惊人的。

对于公司的管理者而言,告诉开发同事自己的需求,期待他们离开一会儿,回来的时候就带来一个满足需求的系统,这一做法是很吸引人。然而,这种操作只会带来低劣的质量,进而导致项目失败。

成功的项目需要客户规律和频繁的反馈。不同于依赖一纸合同和一份工作量陈述,软件的客户应该和开发团队在一起工作,给团队的工作提供频繁的反馈。

指定需求、时间计划和经费的项目从根本上就是错误的。在大多数情况下,这些条约远在项目完成(有时候远远在合同被签订之前)之前就变得毫无意义。保证开发团队和客户能一起工作才是最好的合同。

举一个合同成功的例子。1994年,我谈了一个50万行代码的大型遗留项目。每月,我们开发团队只拿相对较低的报酬,在交付大的功能模块时,才会获得全款。那些功能模块并没有被合同详细指定。相反,合同只是声明当功能模块通过客户的验收测试后,才会支付相应的酬劳。验收测试的细节也没有在合同中详细指定。

在这个项目中,我们和客户密切合作。基本上,每周五我们就发布一个软件版本。在下周的周一或者周二,客户提交一系列的修改。我们一起对这些修改进行优先级排序,然后放入接下来的计划中。客户和我们一起工作让验收测试变得很顺畅,他也知道哪些功能模块何时能满足需要,因为他亲眼见证了软件的演进过程。

这个项目的需求处于不断变化的状态。重大的变化并不少见。有整个功能模块被移除,也有新的功能模块被插入。不过,合同和项目都顺利生存下来了。成功的关键是和客户的紧密合作,而且合同保证了合作关系,而不是尝试划定范围的细节以及固定经费下的时间计划。

响应变化优先于遵循计划

能否响应变化往往决定着软件项目的成功和失败。制定计划时,需要保持灵活,时刻准备着来自业务和技术的改变。

软件项目的过程无法规划得太远。首先,商业环境很可能变化,从而导致需求发生更改。其次,客户看到系统开始工作之后很可能改变需求。最后,即便知道并且确信需求不会改变,也很难估算出需要多久才能开发完成。

对于新晋管理者,做一个好看的项目全局PERT(2)(Program Evaluation and Review Technique)图或者甘特图贴到墙上,是很有吸引力的。他们会觉得这幅图表意味着掌握全局,他们可以追踪个人的任务项,打个叉表示任务完成。他们也可以比较计划完成时间和实际完成时间的差异,然后做出反应。

这类结构的图表有什么真正的缺陷呢?一旦团队深入了解系统,客户明白了自己的需要,图表上的某些任务就变得没有必要了,其他的任务会被发掘出来。简单地说,计划会变化,而不仅仅是时间会变。

更好的计划策略是为接下来的两周安排详细计划,接下来三个月安排比较粗糙的计划,再远就是非常粗略的计划。对于接下来的三个月时间,只要粗略地知道需求就好。对于一年以后的系统,只要有个模糊的想法就行。

这种逐渐模糊的计划方式意味着只有紧急的任务才值得制定详细计划。一旦详细计划被制定出来,就很难改变,因为团队需要大量时间和精力来实施。然而,由于这个计划只管理几周时间,剩下的时间可以保持灵活。

原则

上述价值启发了以下12条原则,即敏捷实践区别于厚重过程方法的关键特点。

1.我们最看重的是,通过及早、持续交付有价值的软件,来满足客户的需求。

MIT《斯隆管理评论》杂志刊登过一篇文章,分析了对公司构建高质量产品有帮助的软件开发过程。这篇文章发现了很多对最终系统质量有重大影响的实践。其中一项实践表明,尽早交付部分功能的系统和系统质量之间有很强的相关性。文章指出,初期交付的功能越少,最终交付的系统质量越高。文中另一项发现是,增量频繁交付和最终质量也有强相关性。交付越频繁,最终的质量也越高。敏捷实践会尽早地、频繁地交付。我们努力在项目刚开始的几周内就交付一个具有基本功能的系统。然后,以每两周增量迭代的方式,持续地交付系统。如果客户认为目前的功能已经足够了,他们就可以把系统部署到生产环境。或者,简单评审一下当前已有的功能,然后指出想要的变更。

2.欢迎需求有变化,即使是在软件开发后期。轻量级的敏捷流程可以驾驭任何有利于提升客户竞争优势的变化。

这是一份关于态度的声明。敏捷过程的参与者不惧怕变化。他们认为改变需求是好事,因为这意味着团队学会了很多可以满足市场需要的知识。敏捷团队会非常努力地保证软件的灵活性,这样,当需求变化时,对系统造成的影响是很小的。在本书的后续部分,我们会学习一些面向对象设计的原则和模式,这些内容会帮助我们维持这种灵活性。

3.频繁交付能用起来的软件,频率从两周到两个月,倾向于更短的时限。

尽早(项目刚开始之后的几周)、频繁(此后每隔几周)地交付可工作的软件。我们不赞成交付大量的文档或者计划,因为它们不是真正的交付物,我们关注的是交付满足客户需要的软件。

4.业务人员和开发人员必须合作,这样的合作贯穿于整个项目中的每一天。

为了保证项目能以敏捷的方式开展,客户、开发人员以及相关利益者就必须进行有意义的、频繁的交互。软件项目不像发射之后就能自动导航的武器,它必须不断地引导。

5.围绕着主动性强的个人来立项。为他们提供必要的环境和支持,同时信任他们能够干成事情。

给他们提供所需要的环境和支持,并且相信他们能够完成工作。在敏捷项目中,人被认为是取得成功最关键的因素。所有其他的因素,比如过程、环境和管理等,都是次要的,并且,当这些因素对人有负面影响时,就要改变它们。例如,如果办公环境对团队造成阻碍,就必须改造办公环境。如果某些过程形成阻碍,这些过程就得整改。

6.开发团队内部以及跨团队之间,最有效和最高效的信息传递方式是,面对面进行对话。

在敏捷项目中,成员面对面交谈。面对面交谈是最主要的沟通方式,也会有文档,但是文档不会包含项目的所有信息。敏捷团队不需要书面的规格、计划或者设计文档,除非这些文档是紧急且重要的,团队成员才会去写,但这不是默认的沟通方式,面对面交谈才是。

7.能用起来的软件,就是衡量进度的基本依据。

敏捷项目是通过统计当前软件满足多少客户的需求来度量项目进度的。他们不会根据所处的开发阶段、已经写好的文档的数量或者已经创建的基础设施代码行数来度量进度。只有当30%的必需功能可以工作时,才可以确定30%的完成度。

8.敏捷流程倡导可持续的开发。发起人、开发人员和用户都能够长期保持一种稳定、可持续的节拍。

责任人、开发者和用户应该能保持长期的、恒定的开发速度敏捷项目不是50米短跑,而是马拉松长跑。团队不是一开始马力全开并试图在项目开发期间维持那个速度。相反,他们会以快速但可持续的速度前进。跑得太快会导致团队精疲力尽,短期冲刺,直至崩溃。敏捷团队会测量自己的速度。他们不允许自己过劳,不会借用明天的精力多完成一点儿今天的工作。他们工作在一个可以让整个项目开发始终保持最高质量标准的速度上。

9.持续保持对技术卓越和设计优良的关注,这是强化敏捷能力的前提。

高质量是高开发速度的关键。保持软件尽可能的整洁健壮是开发软件的快车道。因而,所有的敏捷团队都致力于编写最高质量的代码。他们不会弄乱代码后告诉自己,有时间了再去清理。如果今天弄乱了代码,他们就会在当天下班前清理干净。

10.简洁为本,极简是消除浪费的艺术。

敏捷团队不会试图去构建那些华而不实的系统,他们总是使用和目标一致的最简单的方法。他们并不过多关注预测未来会出现的问题,也不会在今天就做出防卫。相反,他们会在今天以最高的质量完成最简单的工作,深信即便未来出现了问题,也可以从容处理。

11.最好的架构、需求和设计,是从自组织团队中涌现出来的。

敏捷团队是自组织的团队。任务不是从外部分配给单个团队成员,而是分配给整个团队,然后再由团队来确定完成任务最佳方式。敏捷团队的成员共同解决项目中的所有问题。每位成员都有权参与项目所有的方面参与权力。不存在单个成员对系统架构、需求或者测试负责的情况。整个团队共同承担那些责任,每位成员都能影响它们。

12.按固定的时间间隔,团队反思提效的方式,进而从行为上做出相应的优化和调整。

每隔一定时间,团队会对如何更有效地工作进行反省,然后做出相应的调整敏捷团队会不断地对团队的组织方式、规则、惯例和关系等进行调整。敏捷团队知道团队所处的环境在不断变化,并且知道为了保持团队的敏捷性,就必须适应环境变化。

小结

每位软件开发人员、每个开发团队的职业目标,都是尽可能给他们的雇主和客户交付价值。可是,我们的项目以令人沮丧地速度失败或者未能交付价值。虽然在项目中采用过程方法是出于好意,但是膨胀的过程方法对于这些项目的失败至少是需要负一点责任的。敏捷软件开发的原则和价值观形成一套帮助团队打破过程膨胀恶性循环的方法。

在写本书的时候,已经有很多敏捷过程可供大家选择。包括SCRUM(www. controlchaos.com),Crystalcrystal(methodologies.org),特征驱动软件开发(Feature Driven Development,FDD),Java Modeling In Color With UML: Enterprise Components and Process, Peter Coad, Eric Lefebvre, and Jeff De Luca, Prentice Hall, 1999),自适应软件开发(Adaptive Software Development,ADP)[Highsmith2000]以及最重要的极限编程(eXtreme Programming,XP)[Beck 1999], [NewKirk 2001]。

参考文献

1. Beck, Kent.Extreme Programming Explained: Embracing Change.Reading, MA: Addison-Wesley, 1999.中文版《极限编程详解:拥抱变化》

2. Newkirk, James, and Robert C . Martin. Extreme Programming in Practice. Upper Saddle River, NJ: Addison-Wesley, 2001.中文版《极限编程实战》

3. Highsmith, James A. Adaptive Software Development: A Collaborative Approach to Managing Complex Systems. New York, NY: Dorset House, 2000.中文版《自适应软件开发:复杂系统管理的协作方法》


(1)中文版编注:海涅(Christian Johann Heinrich Heine,1797—1856),歌德之后德国最重要的诗人。早期的创作主要是抒情诗《歌集》,有不少作曲家为海涅的诗谱曲,差不多有三千多首,其中包括门德尔松谱曲的《乘着歌声的翅膀》。

(2)全称为Program Evaluation and Review Technique,计划评审技术,主要针对不确定性较高的工作项目,以网络图来规划整个项目,排定期望的项目日程。