<<敏捷软件开发:原则、模式与实践>>摘录
第Ⅰ部分敏捷开发
人们之间的交互是复杂的并且从来都没有很明确的效果,但是它们却是工作中最为重要的方面。
——Tom DeMacro 和Timothy Lister
《人件》,第5页
原则(principle)、模式(pattern)和实践(practice)都是重要的,但是使它们发挥作用的是人。
正如Alistair Cockburm 所说的①,“过程和方法对于项目的结果只有次要的影响。首要的影响是人。”
如果把程序员团队看作是由过程驱动的组件(component)所组成的系统,那么就无法对它们进行管理。人不是“插入即兼容的编程装置。”②如果想要项目取得成功,就必须构建起具有合作精神的、自组织(self-organizing)的团队。
那些鼓励构建这种团队的公司比那些认为软件团队不过是由无关紧要的、雷同的一群人的堆砌的公司具有大得多的竞争优势。有凝聚力的团队将具有最强大的软件开发力量。
-----------------------
① 私人交谈。
② 此语出自Kent Beck。
第1 章敏捷实践
教堂尖顶上的风标,即使由钢铁制成,如果不懂得顺应风势的艺术,一样会立即被暴风所摧毁。
——海因里希Ÿ海涅(1797-1856,德国诗人)
许多人都经历过由于没有实践的指导而导致的项目噩梦。缺乏有效的实践会导致不可预测性、重复的错误以及努力的白白浪费。延期的进度、增长的预算和低劣的质量致使客户对我们丧失信心。更长时间的工作却生产出更加低劣的软件产品,也使得开发人员感到沮丧。
一旦经历了这样的惨败,就会害怕重蹈覆辙。这种恐惧激发我们创建一个过程来约束我们的活动、要求某些中间制品(artifacts )输出。我们根据过去的经验来规定这些约束和输出,挑选那些在以前的项目中看起来好像工作得不错的方法。我们希望这些方法这次还会有效,从而消除我们的恐惧。
然而,项目并没有简单到使用一些约束和中间制品就能够可靠地防止错误的地步。当连续地犯错误时,我们会对错误进行诊断,并在过程中增加了更多的约束和中间制品来防止以后重犯这样的错误。经过多次这样的增加以后,我们就会不堪巨大、笨重的过程的重负,极大地削弱我们完成工作的能力。
一个大而笨重的过程会产生它本来企图去解决的问题。它降低了团队的开发效率,使得进度延期,预算超支。它降低了团队的响应能力,使得团队经常创建错误的产品。遗憾的是,许多团队认为,这种结果是因为他们没有采用更多的过程方法引起的。因此,在这种失控的过程膨胀中,过程会变得越来越庞大。
用失控的过程膨胀来描述公元2000 年间许多软件公司中的情形是很合适的。虽然有许多团队在工作中并没有使用过程方法,但是采用庞大、重型的过程方法的趋势却在快速地增长,在大公司中尤其如此(参见附录C)。
1.1 敏捷联盟
2001 年初,由于看到许多公司的软件团队陷入了不断增长的过程的泥潭,一批业界专家聚集在一起概括出了一些可以让软件开发团队具有快速工作、响应变化能力的价值观(value)和原则。他们称自己为敏捷(Agile)联盟①。在随后的几个月中,他们创建出了一份价值观声明。也就是敏捷联盟宣言(The Manifesto of the Agile Alliance)。
敏捷联盟宣言
敏捷软件开发宣言
我们通过亲身实践以及帮助他人实践,找到了更好的软件开发方法。通过这项工作,我们认为:
l 个体和交互 胜过 过程和工具
l 可以工作的软件 胜过 面面俱到的文档
l 客户合作 胜过 合同谈判
l 响应变化 胜过 遵循计划
虽然右项也有价值,但是我们认为左项具有更大的价值。
Kent Beck James Grenning Robert C. Martin
Mike Beedle Jim Highsmith Steve Mellor
Arie van Bennekum Andrew Hunt Ken Schwaber
Alistair Cockburn Ron Jeffries Jeff Sutherland
Ward Cunningham Jon Kern Dave Thomas
Martin Fowler Brian Marick
1.个体和交互胜过过程和工具
人是获得成功的最为重要的因素。如果团队中没有优秀的成员,那么就是使用好的过程也不能从失败中挽救项目,但是,不好的过程却可以使最优秀的团队成员失去效用。如果不能作为一个团队进行工作,那么即使拥有一批优秀的成员也一样会惨败。
一个优秀的团队成员未必就是一个一流的程序员。一个优秀的团队成员可能是一个平均水平的程序员,但是却能够很好地和他人合作。合作、沟通以及交互能力要比单纯的编程能力更为重要。一个由平均水平程序员组成的团队,如果具有良好的沟通能力,将要比那些虽然拥有一批高水平程序员,但是成员之间却不能进行交流的团队更有可能获得成功。
合适的工具对于成功来说是非常重要的。像编译器、IDE、源代码控制系统等,对于团队的开发者正确地完成他们的工作是至关重要的。然而,工具的作用可能会被过分地夸大。使用过多的庞大、笨重的工具就像缺少工具一样,都是不好的。
我的建议是从使用小工具开始。尝试一个工具,直到发现它无法适用时才去更换它。不是急着去购买那些先进的、价格昂贵的源代码控制系统,相反先使用一个免费的系统直到能够证明该系统已经不再适用。在决定为团队购买最好的CASE 工具许可证(license)前,先使用白板和方格纸,直到有足够的理由表明需要更多的功能。在决定使用庞大的、高性能的数据库系统前,先使用平面文件(flat file)。不要认为更大的、更好的工具可以自动地帮你做的更好。通常,它们造成的障碍要大于带来的帮助。
记住,团队的构建要比环境的构建重要的多。许多团队和管理者就犯了先构建环境,然后期望团队自动凝聚在一起的错误。相反,应该首先致力于构建团队,然后再让团队基于需要来配置环境。
2.可以工作的软件胜过面面俱到的文档
没有文档的软件是一种灾难。代码不是传达系统原理和结构的理想媒介。团队更需要编制易于阅读的文档,来对系统及其设计决策的依据进行描述。
然而,过多的文档比过少的文档更糟。编制众多的文档需要花费大量的时间,并且要使这些文档和代码保持同步,就要花费更多的时间。如果文档和代码之间失去同步,那么文档就会变成庞大的、复杂的谎言,会造成重大的误导。
对于团队来说,编写并维护一份系统原理和结构方面的文档将总是一个好主意,但是那份文档应该是短小的(short)并且主题突出的(salient)。“短小的”意思是说,最多有一二十页。“主题突出的”意思是说,应该仅论述系统的高层结构和概括的设计原理。
如果全部拥有的仅仅是一份简短的系统原理和结构方面的文档,那么如何来培训新的团队成员,使他们能够从事系统相关的工作呢?我们会非常密切地和他们工作在一起。我们紧挨着他们坐下来帮助他们,把我们的知识传授给他们。我们通过近距离的培训和交互使他们成为团队的一部分。
在给新的团队成员传授知识方面,最好的两份文档是代码和团队。代码真实地表达了它所做的事情。虽然从代码中提取系统的原理和结构信息可能是困难的,但是代码是唯一没有二义性的信息源。在团队成员的头脑中,保存着时常变化的系统的脉络图(road map)。人和人之间的交互是把这份脉络图传授给他人的最快、最有效的方式。
许多团队因为注重文档而非软件,导致进度拖延。这常常是一个致命的缺陷。有一个叫做“Martin文档第一定律(Martin’s first law of document)”的简单规则可以预防该缺陷的发生:
直到迫切需要并且意义重大时,才来编制文档。
3.客户合作胜过合同谈判
不能像订购日用品一样来订购软件。你不能够仅仅写下一份关于你想要的软件的描述,然后就让人在固定的时间内以固定的价格去开发它。所有用这种方式来对待软件项目的尝试都以失败而告终。有时,失败是惨重的。
告诉开发团队想要的东西,然后期望开发团队消失一段时间后就能够交付一个满足需要的系统来,这对于公司的管理者来说是具有诱惑力的。然而,这种操作模式将导致低劣的质量和失败。
成功的项目需要有序、频繁的客户反馈。不是依赖于合同或者关于工作的陈述,而是让软件的客户和开发团队密切地工作在一起,并尽量经常地提供反馈。
一个指明了需求、进度以及项目成本的合同存在根本上的缺陷。在大多数的情况下,合同中指明的条款远在项目完成之前就变得没有意义①。那些为开发团队和客户的协同工作方式提供指导的合同才是最好的合同。
我在1994 年为一个大型的、需要多年完成的、有50 万行代码的项目达成的合同,可以作为一个成功合同的样例。作为开发团队的我们,每个月的报酬相对是比较低的。大部分的报酬要在我们交付了某些大的功能块后才支付。那些功能块没有在合同中详细的指明。合同中仅仅声称在一个功能块通过了客户的验收测试时才支付该功能块的报酬。那些验收测试的细节也没有在合同中指明。
在这个项目开发期间,我们和客户紧密的工作在一起。几乎每个周五,我们都会把软件提交给客户。到下一周的周一或者周二,客户会给我们一份关于软件的变更列表。我们会把这些变更放在一起排定优先级,然后把它们安排在随后几周的工作中。客户和我们如此紧密的工作在一起,以至于验收测试根本就不是问题。因为他们周复一周地观察着每个功能块的演进,所以他们知道何时这个功能块能够满足他们的需要。
这个项目的需求基本处于一个持续变化的状态。大的变更是很平常的。在这期间,也会出现整个功能块被去掉,而另外的功能块被加进来的情况。然而,合同和项目都经受住了这些变更,并获得成功。成功的关键在于和客户之间认真的协作,并且合同指导了这种协作,而不是试图去规定项目范围的细节和固定成本下的进度。
4.响应变化胜过遵循计划
响应变化的能力常常决定着一个软件项目的成败。当我们构建计划时,应该确保计划是灵活的并且易于适应商务和技术方面的变化。
计划不能考虑得过远。首先,商务环境很可能会变化,这会引起需求的变动。其次,一旦客户看到系统开始运作,他们很可能会改变需求。最后,即使我们熟悉需求,并且确信它们不会改变,我们仍然不能很好地估算出开发它们需要的时间。
对于一个缺乏经验的管理者来说,创建一张优美的PERT 或者Gantt 图并把他们贴到墙上是很有诱惑力的。他们也许觉得这张图赋予了他们控制整个项目的权力。他们能够跟踪单个人的任务,并在任务完成时将任务从图上去除。他们可以对实际完成的日期和计划完成的日期进行比较,并对出现的任何偏差做出反应。
实际上发生的是这张图的组织结构不再适用。当团队增加了对于系统的认识,当客户增加了对于需求的认识,图中的某些任务会变得没有必要。另外一些任务会被发现并增加到图中。简而言之,计划将会遭受形态(shape)上的改变,而不仅仅是日期上的改变。
较好的做计划的策略是:为下两周做详细的计划,为下三个月作粗略的计划,再以后就作极为粗糙的计划。我们应该清楚地知道下两周要完成的任务,粗略的了解一下以后三个月要实现的需求。至于系统一年后将要做什么,有一个模糊的想法就行了。
计划中这种逐渐降低的细致度,意味着我们仅仅对于迫切的任务才花费时间进行详细的计划。一旦制定了这个详细的计划,就很难进行改变,因为团队会根据这个计划启动工作并有了相应的投入。然而,由于计划仅仅支配了几周的时间,计划的其余部分仍然保持着灵活性。
1.2 原则
从上述的价值观中引出了下面的12 条原则,它们是敏捷实践区别于重型过程的特征所在。
1.我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。
MIT Sloan 管理评论杂志刊登过一篇论文,分析了对于公司构建高质量产品方面有帮助的软件开发实践①。该论文发现了很多对于最终系统质量有重要影响的实践。其中一个实践表明,尽早地交付具有部分功能的系统和系统质量之间具有很强的相关性。该论文指出,初期交付的系统中所包含的功能越少,最终交付的系统的质量就越高。
该论文的另一项发现是,以逐渐增加功能的方式经常性地交付系统和最终质量之间有非常强的相关性。交付得越频繁,最终产品的质量就越高。
敏捷实践会尽早地、经常地进行交付。我们努力在项目刚开始的几周内就交付一个具有基本功能的系统。然后,我们努力坚持每两周就交付一个功能渐增的系统。
如果客户认为目前的功能已经足够了,客户可以选择把这些系统加入到产品中。
或者,他们可以简单地选择再检查一遍已有的功能,并指出他们想要做的改变。
2.即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。
这是一个关于态度的声明。敏捷过程的参与者不惧怕变化。他们认为改变需求是好的事情,因为那些改变意味着团队已经学到了很多如何满足市场需要的知识。
敏捷团队会非常努力地保持软件结构的灵活性,这样当需求变化时,对于系统造成的影响是最小的。在本书的后面部分,我们会学习一些面向对象设计的原则和模式,这些内容会帮助我们维持这种灵活性。
3.经常性地交付可以工作的软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
我们交付可以工作的软件(working software ),并且尽早地(项目刚开始很少的几周后)、经常性地(此后每隔很少的几周)交付它。我们不赞成交付大量的文档或者计划。我们认为那些不是真正要交付的东西。我们关注的目标是交付满足客户需要的软件。
4.在整个项目开发期间,商务人员和开发人员必须天天都工作在一起。
为了能够以敏捷的方式进行项目的开发,客户、开发人员以及涉众之间就必须要进行有意义的、频繁的交互。软件项目不像发射出去就能够自动导航的武器,必须要对软件项目进行持续不断地引导。
5.围绕被激励起来的个体来构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。
在敏捷项目中,人被认为是项目取得成功的最重要的因素。所有其他的因素——过程、环境、管理等等——都被认为是次要的,并且当它们对于人有负面的影响时,就要对它们进行改变。
例如,如果办公环境对团队的工作造成阻碍,就必须对办公环境进行改变。如果某些过程步骤对团队的工作造成阻碍,就必须对那些过程步骤进行改变。
6.在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈。
在敏捷项目中,人们之间相互进行交谈。首要的沟通方式就是交谈。也许会编写文档,但是不会企图在文档中包含所有的项目信息。敏捷团队不需要书面的规范、书面的计划或者书面的设计。团队成员可以去编写文档,如果对于这些文档的需求是迫切并且意义重大的,但是文档不是默认的沟通方式。默认的沟通方式是交谈。
7.工作的软件是首要的进度度量标准。
敏捷项目通过度量当前软件满足客户需求的数量来度量开发进度。它们不是根据所处的开发阶段、已经编写的文档的多少或者已经创建的基础设施( infrastructure)代码的数量来度量开发进度的。只有当30%的必须功能可以工作时,才可以确定进度完成了30%。
8.敏捷过程提倡可持续的开发速度。责任人(sponsors)、开发者和用户应该能够保持一个长期的、恒定的开发速度。
敏捷项目不是50 米短跑;而是马拉松长跑。团队不是以全速启动并试图在项目开发期间维持那个速度;相反,他们以快速但是可持续的速度行进。
跑得过快会导致团队精力耗尽、出现短期行为以致崩溃。敏捷团队会测量他们自己的速度。他们不允许自己过于疲惫。他们不会借用明天的精力来在今天多完成一点工作。他们工作在一个可以使在整个项目开发期间保持最高质量标准的速度上。
9.不断地关注优秀的技能和好的设计会增强敏捷能力。
高的产品质量是获取高的开发速度的关键。保持软件尽可能的清洁、健壮是快速开发软件的途径。因而,所有的敏捷团队成员都致力于只编写他们能够编写的最高质量的代码。他们不会制造混乱然后告诉自己等有更多的时间时再来清理它们。如果他们在今天制造了混乱,他们会在今天把混乱清理干净。
10.简单——使未完成的工作最大化的艺术——是根本的。
敏捷团队不会试图去构建那些华而不实的系统,他们总是更愿意采用和目标一致的最简单的方法。他们并不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫。相反,他们在今天以最高的质量完成最简单的工作,深信如果在明天发生了问题,也会很容易进行处理。
11.最好的构架、需求和设计出自于自组织的团队。
敏捷团队是自组织的团队。任务不是从外部分配给单个团队成员,而是分配给整个团队,然后再由团队来确定完成任务的最好方法。
敏捷团队的成员共同来解决项目中所有方面的问题。每一个成员都具有项目中所有方面的参与权力。不存在单一的团队成员对系统构架、需求或者测试负责的情况。整个团队共同承担那些职责,每一个团队成员都能够影响它们。
12.每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。
敏捷团队会不断地对团队的组织方式、规则、规范、关系等进行调整。敏捷团队知道团队所处的环境在不断的变化,并且知道为了保持团队的敏捷性,就必须要随环境一起变化。
1.3 结论
每一个软件开发人员、每一个开发团队的职业目标,都是给他们的雇主和客户交付最大可能的价值。可是,我们的项目以令人沮丧的速度失败,或者未能交付任何价值。虽然在项目中采用过程方法是出于好意的,但是膨胀的过程方法对于我们的失败至少是应该负一些责任的。敏捷软件开发的原则和价值观构成了一个可以帮助团队打破过程膨胀循环的方法,这个方法关注的是可以达到团队目标的一些简单的技术。
在撰写本书的时候,已经有许多的敏捷过程可供选择。包括:SCRUM①,Crystal②,特性驱动软件开发( Feature Driven Developmen,简称FDD)③,自适应软件开发(Adaptive software Development,简称ADP)④,以及最重要的极限编程(eXtreme Programming,简称XP)⑤。
参考文献
1. Beck, Kent. Extreme Programming Explained: Embracing Changes. Reading, MA: Addison-Wesley, 1999.
2. Newkirk, James, and Robert C. Martin. Extreme Programming in Practice. Upper Saddle River, NJ: Addsion-Wesley, 2001.
3. Highsmith, James A. Adapting Software Development: A Collaborative Approach to Managing Complex System. New York, NY: Dorset House, 2000.
人们之间的交互是复杂的并且从来都没有很明确的效果,但是它们却是工作中最为重要的方面。
——Tom DeMacro 和Timothy Lister
《人件》,第5页
原则(principle)、模式(pattern)和实践(practice)都是重要的,但是使它们发挥作用的是人。
正如Alistair Cockburm 所说的①,“过程和方法对于项目的结果只有次要的影响。首要的影响是人。”
如果把程序员团队看作是由过程驱动的组件(component)所组成的系统,那么就无法对它们进行管理。人不是“插入即兼容的编程装置。”②如果想要项目取得成功,就必须构建起具有合作精神的、自组织(self-organizing)的团队。
那些鼓励构建这种团队的公司比那些认为软件团队不过是由无关紧要的、雷同的一群人的堆砌的公司具有大得多的竞争优势。有凝聚力的团队将具有最强大的软件开发力量。
-----------------------
① 私人交谈。
② 此语出自Kent Beck。
第1 章敏捷实践
教堂尖顶上的风标,即使由钢铁制成,如果不懂得顺应风势的艺术,一样会立即被暴风所摧毁。
——海因里希Ÿ海涅(1797-1856,德国诗人)
许多人都经历过由于没有实践的指导而导致的项目噩梦。缺乏有效的实践会导致不可预测性、重复的错误以及努力的白白浪费。延期的进度、增长的预算和低劣的质量致使客户对我们丧失信心。更长时间的工作却生产出更加低劣的软件产品,也使得开发人员感到沮丧。
一旦经历了这样的惨败,就会害怕重蹈覆辙。这种恐惧激发我们创建一个过程来约束我们的活动、要求某些中间制品(artifacts )输出。我们根据过去的经验来规定这些约束和输出,挑选那些在以前的项目中看起来好像工作得不错的方法。我们希望这些方法这次还会有效,从而消除我们的恐惧。
然而,项目并没有简单到使用一些约束和中间制品就能够可靠地防止错误的地步。当连续地犯错误时,我们会对错误进行诊断,并在过程中增加了更多的约束和中间制品来防止以后重犯这样的错误。经过多次这样的增加以后,我们就会不堪巨大、笨重的过程的重负,极大地削弱我们完成工作的能力。
一个大而笨重的过程会产生它本来企图去解决的问题。它降低了团队的开发效率,使得进度延期,预算超支。它降低了团队的响应能力,使得团队经常创建错误的产品。遗憾的是,许多团队认为,这种结果是因为他们没有采用更多的过程方法引起的。因此,在这种失控的过程膨胀中,过程会变得越来越庞大。
用失控的过程膨胀来描述公元2000 年间许多软件公司中的情形是很合适的。虽然有许多团队在工作中并没有使用过程方法,但是采用庞大、重型的过程方法的趋势却在快速地增长,在大公司中尤其如此(参见附录C)。
1.1 敏捷联盟
2001 年初,由于看到许多公司的软件团队陷入了不断增长的过程的泥潭,一批业界专家聚集在一起概括出了一些可以让软件开发团队具有快速工作、响应变化能力的价值观(value)和原则。他们称自己为敏捷(Agile)联盟①。在随后的几个月中,他们创建出了一份价值观声明。也就是敏捷联盟宣言(The Manifesto of the Agile Alliance)。
敏捷联盟宣言
敏捷软件开发宣言
我们通过亲身实践以及帮助他人实践,找到了更好的软件开发方法。通过这项工作,我们认为:
l 个体和交互 胜过 过程和工具
l 可以工作的软件 胜过 面面俱到的文档
l 客户合作 胜过 合同谈判
l 响应变化 胜过 遵循计划
虽然右项也有价值,但是我们认为左项具有更大的价值。
Kent Beck James Grenning Robert C. Martin
Mike Beedle Jim Highsmith Steve Mellor
Arie van Bennekum Andrew Hunt Ken Schwaber
Alistair Cockburn Ron Jeffries Jeff Sutherland
Ward Cunningham Jon Kern Dave Thomas
Martin Fowler Brian Marick
1.个体和交互胜过过程和工具
人是获得成功的最为重要的因素。如果团队中没有优秀的成员,那么就是使用好的过程也不能从失败中挽救项目,但是,不好的过程却可以使最优秀的团队成员失去效用。如果不能作为一个团队进行工作,那么即使拥有一批优秀的成员也一样会惨败。
一个优秀的团队成员未必就是一个一流的程序员。一个优秀的团队成员可能是一个平均水平的程序员,但是却能够很好地和他人合作。合作、沟通以及交互能力要比单纯的编程能力更为重要。一个由平均水平程序员组成的团队,如果具有良好的沟通能力,将要比那些虽然拥有一批高水平程序员,但是成员之间却不能进行交流的团队更有可能获得成功。
合适的工具对于成功来说是非常重要的。像编译器、IDE、源代码控制系统等,对于团队的开发者正确地完成他们的工作是至关重要的。然而,工具的作用可能会被过分地夸大。使用过多的庞大、笨重的工具就像缺少工具一样,都是不好的。
我的建议是从使用小工具开始。尝试一个工具,直到发现它无法适用时才去更换它。不是急着去购买那些先进的、价格昂贵的源代码控制系统,相反先使用一个免费的系统直到能够证明该系统已经不再适用。在决定为团队购买最好的CASE 工具许可证(license)前,先使用白板和方格纸,直到有足够的理由表明需要更多的功能。在决定使用庞大的、高性能的数据库系统前,先使用平面文件(flat file)。不要认为更大的、更好的工具可以自动地帮你做的更好。通常,它们造成的障碍要大于带来的帮助。
记住,团队的构建要比环境的构建重要的多。许多团队和管理者就犯了先构建环境,然后期望团队自动凝聚在一起的错误。相反,应该首先致力于构建团队,然后再让团队基于需要来配置环境。
2.可以工作的软件胜过面面俱到的文档
没有文档的软件是一种灾难。代码不是传达系统原理和结构的理想媒介。团队更需要编制易于阅读的文档,来对系统及其设计决策的依据进行描述。
然而,过多的文档比过少的文档更糟。编制众多的文档需要花费大量的时间,并且要使这些文档和代码保持同步,就要花费更多的时间。如果文档和代码之间失去同步,那么文档就会变成庞大的、复杂的谎言,会造成重大的误导。
对于团队来说,编写并维护一份系统原理和结构方面的文档将总是一个好主意,但是那份文档应该是短小的(short)并且主题突出的(salient)。“短小的”意思是说,最多有一二十页。“主题突出的”意思是说,应该仅论述系统的高层结构和概括的设计原理。
如果全部拥有的仅仅是一份简短的系统原理和结构方面的文档,那么如何来培训新的团队成员,使他们能够从事系统相关的工作呢?我们会非常密切地和他们工作在一起。我们紧挨着他们坐下来帮助他们,把我们的知识传授给他们。我们通过近距离的培训和交互使他们成为团队的一部分。
在给新的团队成员传授知识方面,最好的两份文档是代码和团队。代码真实地表达了它所做的事情。虽然从代码中提取系统的原理和结构信息可能是困难的,但是代码是唯一没有二义性的信息源。在团队成员的头脑中,保存着时常变化的系统的脉络图(road map)。人和人之间的交互是把这份脉络图传授给他人的最快、最有效的方式。
许多团队因为注重文档而非软件,导致进度拖延。这常常是一个致命的缺陷。有一个叫做“Martin文档第一定律(Martin’s first law of document)”的简单规则可以预防该缺陷的发生:
直到迫切需要并且意义重大时,才来编制文档。
3.客户合作胜过合同谈判
不能像订购日用品一样来订购软件。你不能够仅仅写下一份关于你想要的软件的描述,然后就让人在固定的时间内以固定的价格去开发它。所有用这种方式来对待软件项目的尝试都以失败而告终。有时,失败是惨重的。
告诉开发团队想要的东西,然后期望开发团队消失一段时间后就能够交付一个满足需要的系统来,这对于公司的管理者来说是具有诱惑力的。然而,这种操作模式将导致低劣的质量和失败。
成功的项目需要有序、频繁的客户反馈。不是依赖于合同或者关于工作的陈述,而是让软件的客户和开发团队密切地工作在一起,并尽量经常地提供反馈。
一个指明了需求、进度以及项目成本的合同存在根本上的缺陷。在大多数的情况下,合同中指明的条款远在项目完成之前就变得没有意义①。那些为开发团队和客户的协同工作方式提供指导的合同才是最好的合同。
我在1994 年为一个大型的、需要多年完成的、有50 万行代码的项目达成的合同,可以作为一个成功合同的样例。作为开发团队的我们,每个月的报酬相对是比较低的。大部分的报酬要在我们交付了某些大的功能块后才支付。那些功能块没有在合同中详细的指明。合同中仅仅声称在一个功能块通过了客户的验收测试时才支付该功能块的报酬。那些验收测试的细节也没有在合同中指明。
在这个项目开发期间,我们和客户紧密的工作在一起。几乎每个周五,我们都会把软件提交给客户。到下一周的周一或者周二,客户会给我们一份关于软件的变更列表。我们会把这些变更放在一起排定优先级,然后把它们安排在随后几周的工作中。客户和我们如此紧密的工作在一起,以至于验收测试根本就不是问题。因为他们周复一周地观察着每个功能块的演进,所以他们知道何时这个功能块能够满足他们的需要。
这个项目的需求基本处于一个持续变化的状态。大的变更是很平常的。在这期间,也会出现整个功能块被去掉,而另外的功能块被加进来的情况。然而,合同和项目都经受住了这些变更,并获得成功。成功的关键在于和客户之间认真的协作,并且合同指导了这种协作,而不是试图去规定项目范围的细节和固定成本下的进度。
4.响应变化胜过遵循计划
响应变化的能力常常决定着一个软件项目的成败。当我们构建计划时,应该确保计划是灵活的并且易于适应商务和技术方面的变化。
计划不能考虑得过远。首先,商务环境很可能会变化,这会引起需求的变动。其次,一旦客户看到系统开始运作,他们很可能会改变需求。最后,即使我们熟悉需求,并且确信它们不会改变,我们仍然不能很好地估算出开发它们需要的时间。
对于一个缺乏经验的管理者来说,创建一张优美的PERT 或者Gantt 图并把他们贴到墙上是很有诱惑力的。他们也许觉得这张图赋予了他们控制整个项目的权力。他们能够跟踪单个人的任务,并在任务完成时将任务从图上去除。他们可以对实际完成的日期和计划完成的日期进行比较,并对出现的任何偏差做出反应。
实际上发生的是这张图的组织结构不再适用。当团队增加了对于系统的认识,当客户增加了对于需求的认识,图中的某些任务会变得没有必要。另外一些任务会被发现并增加到图中。简而言之,计划将会遭受形态(shape)上的改变,而不仅仅是日期上的改变。
较好的做计划的策略是:为下两周做详细的计划,为下三个月作粗略的计划,再以后就作极为粗糙的计划。我们应该清楚地知道下两周要完成的任务,粗略的了解一下以后三个月要实现的需求。至于系统一年后将要做什么,有一个模糊的想法就行了。
计划中这种逐渐降低的细致度,意味着我们仅仅对于迫切的任务才花费时间进行详细的计划。一旦制定了这个详细的计划,就很难进行改变,因为团队会根据这个计划启动工作并有了相应的投入。然而,由于计划仅仅支配了几周的时间,计划的其余部分仍然保持着灵活性。
1.2 原则
从上述的价值观中引出了下面的12 条原则,它们是敏捷实践区别于重型过程的特征所在。
1.我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意。
MIT Sloan 管理评论杂志刊登过一篇论文,分析了对于公司构建高质量产品方面有帮助的软件开发实践①。该论文发现了很多对于最终系统质量有重要影响的实践。其中一个实践表明,尽早地交付具有部分功能的系统和系统质量之间具有很强的相关性。该论文指出,初期交付的系统中所包含的功能越少,最终交付的系统的质量就越高。
该论文的另一项发现是,以逐渐增加功能的方式经常性地交付系统和最终质量之间有非常强的相关性。交付得越频繁,最终产品的质量就越高。
敏捷实践会尽早地、经常地进行交付。我们努力在项目刚开始的几周内就交付一个具有基本功能的系统。然后,我们努力坚持每两周就交付一个功能渐增的系统。
如果客户认为目前的功能已经足够了,客户可以选择把这些系统加入到产品中。
或者,他们可以简单地选择再检查一遍已有的功能,并指出他们想要做的改变。
2.即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。
这是一个关于态度的声明。敏捷过程的参与者不惧怕变化。他们认为改变需求是好的事情,因为那些改变意味着团队已经学到了很多如何满足市场需要的知识。
敏捷团队会非常努力地保持软件结构的灵活性,这样当需求变化时,对于系统造成的影响是最小的。在本书的后面部分,我们会学习一些面向对象设计的原则和模式,这些内容会帮助我们维持这种灵活性。
3.经常性地交付可以工作的软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
我们交付可以工作的软件(working software ),并且尽早地(项目刚开始很少的几周后)、经常性地(此后每隔很少的几周)交付它。我们不赞成交付大量的文档或者计划。我们认为那些不是真正要交付的东西。我们关注的目标是交付满足客户需要的软件。
4.在整个项目开发期间,商务人员和开发人员必须天天都工作在一起。
为了能够以敏捷的方式进行项目的开发,客户、开发人员以及涉众之间就必须要进行有意义的、频繁的交互。软件项目不像发射出去就能够自动导航的武器,必须要对软件项目进行持续不断地引导。
5.围绕被激励起来的个体来构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。
在敏捷项目中,人被认为是项目取得成功的最重要的因素。所有其他的因素——过程、环境、管理等等——都被认为是次要的,并且当它们对于人有负面的影响时,就要对它们进行改变。
例如,如果办公环境对团队的工作造成阻碍,就必须对办公环境进行改变。如果某些过程步骤对团队的工作造成阻碍,就必须对那些过程步骤进行改变。
6.在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈。
在敏捷项目中,人们之间相互进行交谈。首要的沟通方式就是交谈。也许会编写文档,但是不会企图在文档中包含所有的项目信息。敏捷团队不需要书面的规范、书面的计划或者书面的设计。团队成员可以去编写文档,如果对于这些文档的需求是迫切并且意义重大的,但是文档不是默认的沟通方式。默认的沟通方式是交谈。
7.工作的软件是首要的进度度量标准。
敏捷项目通过度量当前软件满足客户需求的数量来度量开发进度。它们不是根据所处的开发阶段、已经编写的文档的多少或者已经创建的基础设施( infrastructure)代码的数量来度量开发进度的。只有当30%的必须功能可以工作时,才可以确定进度完成了30%。
8.敏捷过程提倡可持续的开发速度。责任人(sponsors)、开发者和用户应该能够保持一个长期的、恒定的开发速度。
敏捷项目不是50 米短跑;而是马拉松长跑。团队不是以全速启动并试图在项目开发期间维持那个速度;相反,他们以快速但是可持续的速度行进。
跑得过快会导致团队精力耗尽、出现短期行为以致崩溃。敏捷团队会测量他们自己的速度。他们不允许自己过于疲惫。他们不会借用明天的精力来在今天多完成一点工作。他们工作在一个可以使在整个项目开发期间保持最高质量标准的速度上。
9.不断地关注优秀的技能和好的设计会增强敏捷能力。
高的产品质量是获取高的开发速度的关键。保持软件尽可能的清洁、健壮是快速开发软件的途径。因而,所有的敏捷团队成员都致力于只编写他们能够编写的最高质量的代码。他们不会制造混乱然后告诉自己等有更多的时间时再来清理它们。如果他们在今天制造了混乱,他们会在今天把混乱清理干净。
10.简单——使未完成的工作最大化的艺术——是根本的。
敏捷团队不会试图去构建那些华而不实的系统,他们总是更愿意采用和目标一致的最简单的方法。他们并不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫。相反,他们在今天以最高的质量完成最简单的工作,深信如果在明天发生了问题,也会很容易进行处理。
11.最好的构架、需求和设计出自于自组织的团队。
敏捷团队是自组织的团队。任务不是从外部分配给单个团队成员,而是分配给整个团队,然后再由团队来确定完成任务的最好方法。
敏捷团队的成员共同来解决项目中所有方面的问题。每一个成员都具有项目中所有方面的参与权力。不存在单一的团队成员对系统构架、需求或者测试负责的情况。整个团队共同承担那些职责,每一个团队成员都能够影响它们。
12.每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。
敏捷团队会不断地对团队的组织方式、规则、规范、关系等进行调整。敏捷团队知道团队所处的环境在不断的变化,并且知道为了保持团队的敏捷性,就必须要随环境一起变化。
1.3 结论
每一个软件开发人员、每一个开发团队的职业目标,都是给他们的雇主和客户交付最大可能的价值。可是,我们的项目以令人沮丧的速度失败,或者未能交付任何价值。虽然在项目中采用过程方法是出于好意的,但是膨胀的过程方法对于我们的失败至少是应该负一些责任的。敏捷软件开发的原则和价值观构成了一个可以帮助团队打破过程膨胀循环的方法,这个方法关注的是可以达到团队目标的一些简单的技术。
在撰写本书的时候,已经有许多的敏捷过程可供选择。包括:SCRUM①,Crystal②,特性驱动软件开发( Feature Driven Developmen,简称FDD)③,自适应软件开发(Adaptive software Development,简称ADP)④,以及最重要的极限编程(eXtreme Programming,简称XP)⑤。
参考文献
1. Beck, Kent. Extreme Programming Explained: Embracing Changes. Reading, MA: Addison-Wesley, 1999.
2. Newkirk, James, and Robert C. Martin. Extreme Programming in Practice. Upper Saddle River, NJ: Addsion-Wesley, 2001.
3. Highsmith, James A. Adapting Software Development: A Collaborative Approach to Managing Complex System. New York, NY: Dorset House, 2000.