我们在thoughtworks这样的大型项目中应用xp方法的时间超过了15个月。这个项目开始于三年前,那时它有大量的需求文档和几个独立的功能小组。从2000年1月起,我们决定应用xp,虽然当时我们已经知道xp并不适用于大型项目。那时,我们需要向客户提交功能演示,并要通过提交一个工作子集而不仅仅是原型来赢得他们的信心(我们在团队中有超过25名开发人员和大约15名分析员)。但我们并未准备好功能,各个组都使用自己的代码框架,一个完整的应用无从谈起。简短地说,就是客户想要看到点什么,但我们还没有真正的功能。应该说开发的第一迭代期是成功的:我们给客户提交了一个真正的应用子集。成功的首要原因是我们让来自asset, ar 和gui组从事不同工作的开发者融合在一起。当然,其间也有"成长的烦恼":在分析员和开发者之间发生某些个人冲突,但我们成功跨越了这些障碍。那时一切都很美好:我们以飞快的速度成功地提交了功能演示,但随着时间的流逝和项目的继续,有些事情却不如我们所愿。这就是这篇文章要讲述的内容:我们真正的收获在"蜜月"期后,关于凯发k8网页登录如何在一年半中管理一个50人的项目开发并及时完成阶段性的提交(尽管有时并不成功),关于凯发k8网页登录经历的痛苦,我们后续的工作,我们最终学到的以及作为改进要用到下一个项目中的经验。
首先,我们给出我们开始的状况:15个月前我们是如何应用xp的,然后展示我们现在的xp应用情况。也就是说,下面将讨论我们改变技术的原因。这是一个自然选择的过程,它剔除了许多不好的想法,或把它们改造成更有效的方法,使之更适于大型项目。最后我们将总结并给出在大型项目中使用xp的谨慎建议。
大型项目中xp的元素
好吧,让我们来进入正题。我们开发和分析的队伍由大约35名开发人员、15名分析人员和10名qa组成。开发人员依赖分析人员作为项目的客户。尽管有实际的客户,分析人员还是要协同工作以便有选择地做出客户决策。下表演示了[1]所讨论的xp基本元素并简要介绍了这些方面如何应用到项目的各个阶段。我们用这个表来分析我们团队自然选择的实践,以及书本上的xp如何应用到一个超过50人的大型项目中。
计划 | 提交周期 | 比喻 | 设计的简单性 | 测试 | 重构 | |
1/2000 | 大跨度的迭代计划会议。开发和分析组的全部成员整天在一起讨论新的故事卡片和预估。大多数开发者签入(sign up)新的功能。 | 1个月 | 无 | 转变已有的代码基准。已有的代码依然复杂,但新的代码要尽可能简单。这个阶段包括抛弃老的代码和重写那些"今后可能会被用到"的功能代码。 | 单元测试开始于一些新的代码。推动建立一个大的测试基准。qa做所有的功能测试并有权留弃故事卡片。 | 对于旧有代码,如有必要就进行重构。 |
7/2000 | 基本同1/2000,但确实感觉十分低效。多数与会者没能很好地参与。拖沓的讨论,50人的会议是无法忍受的。 | 1个月 | 无 | 以尽可能简单的原则继续设计。完成对已有设计的重构。完成代码会审,旨在全体范围中讨论新设计以便整个团队了解代码和设计的发展趋势。 | 更好的单元测试覆盖更大的范围,尽管没有完全覆盖。代码功能测试帮助覆盖测试范围。 | 多数开发人员埋头于新功能的开发,很少会去做重构。代码基准在迭代期末向qa组提交卡片时变得糟糕起来。 |
1/2001 | 希望能尽快做出每个迭代期间的计划-我们的办法是在正式会议前以小组为单位进行更多的准备工作。 | 2 周 | 无 | 多数的设计基于已有的设计:保留标准,代码会审逐渐停止,因为新的设计和重构尚未完成。 | 试图去掉代码功能测试而代之以屏幕搜刮(screen scraper),若失败就回到代码功能测试 。加入新的单元测试但仍然没有全部覆盖。qa组开始结合界面测试使用自动功能测试。 | 重构开始更频繁,因为部分代码开始变得凌乱不堪。需要清理的原因主要是实现简单和迭代期限使得代码在没有重要重构的情况下增长。 |
6/2001 | 举行一些讨论卡片或相关卡片组的会议,参加者包括对这些功能感兴趣或有经验的开发者和负责这些卡片的分析人员。 | 2 周 | 无 | 队伍中的大多数人及整个qa组准备提交1.0版本给客户。代码的基准分离以便加入没有测试的新功能。对单元测试有更多的依赖。 | 尽管仍有遗漏,测试范围已经基本稳定。qa组不再测试新功能,因为焦点是1.0版本的提交。 | 在发布版上做的重构很少,而在继续开发的版本上,开发人员会很尽责地进行重构,特别是在年初被迫做了更大更痛苦的重构以后. |
结对编程 | 集体所有 | 持续集成 | 40小时周 | 在场客户 | 代码规范 | |
1/2000 | 由于我们决定采用xp,整个团队读了[1]。每个人都做了尝试,多数人被吸引。 | 由于最初阶段的分组是面向功能,因此此时我们并未意识到集体所有 (collective ownership) ,也没有意识到代码的保护。 | 从第一迭代期开始,进行在线集成,参见[2] | 这是一个概念工作时间:因为我们希望客户在场。于是我们会花另外的时间来满足最后期限。 | 事务分析人员是在场的客户,他们15人一组。真正的客户是不在的,由分析人员同他们沟通。 基本上是java的一般语法。 | |
7/2000 | 结对编程依旧盛行:开发者对新功能进行结对编程,但改错和维护工作由单个人来做。也有一些开发者停止了结对编程。 | 当开发者越来越多地接触不同的部分的时候,代码的所有者逐渐显现出来。成员间通过闲谈,代码互审和短小的站立会议(stand up meeting)进行很好的沟通。 | 代码功能测试加入构造过程。 | 为了通过故事卡片,在每个迭代期的最后工作时间达到50至60小时。 | 同上 | 两周一次的代码互审给开发人员一个机会讨论不同子的实现方式。我们可以接受某些子代码的非正式方式。 |
1/2001 | 结对编程更少了,因为这一阶段编码更直接,而有些人在进行重构。 | 因为效率低,站立会议被弃用,但代码的所有显现得更加清晰。开发人员开始专职负责的某部分。 | 稳定_同上。 | 以2周为迭代期,开发人员的工作时间更接近于40小时… | 同上 | 代码互审逐渐减少,设计及编码规范趋于饱和。 |
6/2001 | 定下了规则:所有新功能要应用结对编程,而改错和维护则由一人完成。 | 随着专业化分工的继续,不同的开发小组人员拥有不同部分代码的知识,于是我们将使他们在接下来相应模块的设计中起更活跃的作用,但代码仍是集体共有。 | 稳定同上。 | 同上 | 同上 | 同上 |
极限编程(xp)适用于需求经常发生变化的项目。你的客户对应该做什么可能没有一个固定的想法;一个每隔几个月其功能就要求进行一定的改变。大多数软件项目的需求都处于这样的动态变化之中。与其它的方法相比,xp能够更好地适应这种情况。
xp适用于高风险的项目。 如果客户需要一个新的,而且要求在某天前完成,这里的风险就比较高;如果你的开发组没有做过类似的,风险就更高了;如果该对整个软件业来说都是一个新的挑战,那这风险就可想而知。使用xp可以降低风险和增加成功的可能性。
xp适用于小规模的项目组,一般在2到10人之间。使用xp不需要拥有博士头衔的开发人员,一般的开发人员就可以。但不能在一个大型的项目组中采用xp。我们注意到,对于一个需求动态变化和高风险的项目而言,一小组xp开发人员要比大的开发组更加有效。
xp对项目组的组成人员有要求。组内不仅包括开发人员,还包括经理和客户,所有人员肩并肩地战斗在一起。软件开发中问题的讨论,项目范围和进度的协商,以及功能测试的创建仅靠开发人员是不够的。
xp对可测试性有要求。你必须建立自动的单元测试和功能测试。虽然在某些情况下这个要求不能满足,但事实上你会惊讶地看到通过某种方式仍然可以达到这个要求。比如可以通过修改的设计以使之已于测试。记住,只要你愿意就可以找到一种测试的方式。
xp对生产力也有要求。从已有的报告中,在相同条件下,所有采取xp的项目组都无一例外地比其它项目组的生产力高。但这从来不是xp的目的。xp的真正目的在于按时交付客户需要的软件。如果这对于你的项目而言很重要,你就可以尝试一下xp。
配对编程是极限编程里争议最大的做法之一——支持者和反对者对此的反应都相当强烈。那么什么是配对编程?为什么人们对此的反应这么大?
laurie williams将配对编程(pair programming)描述为“一种编程风格,它由两个员并排在一台计算机上工作,连续协作完成同一个设计、算法、代码或者测试”。从上面的描述我们可以清楚地看出,配对编程的含义不仅仅是编程本身的键入,我个人认为“配对开发(pair development)”应该是对这种活动的更好描述。
配对编程不是一个人简单地看着另一个在做什么——在卓有成效的配对工作里,这两个凯发k8网页登录的合作伙伴常常工作在不同抽象层次,一个人关注的是为实现眼前目标而编写的代码的细节,而另一个人考虑的是更大的前景和下一步要做的事情,这两个人的角色频繁进行更换。这是一项高强度的、严密的,且常常令人疲劳的活动,但是能够创造出经过深思熟虑的高质量代码。
反对配对编程的大多数强烈反应都源于配对编程对社会上业已形成的软件开发习惯的挑战。
对编程的传统看法是在隔离上花一大段时间,在此期间员进入一个“流程”,只与计算机和他们自己的思考模式进行交互。这样做的结果就是,编程往往更受性格内向的人的欢迎,因为这样的人喜欢将社交活动减到最少,而对那些外向的人却吸引力不大,因为他们更希望时时刻刻进行合作。
当然这些都是一般的想法,但是总有不愿意与其他人肩并肩工作员,对他们工作的满意度肯定会受到像配对编程这样的事的影响,了解这种情况是非常重要的。
对配对编程也有反应不太强烈的反对,一般都是与让两个人在一台机器上工作所花费的时间肯定要比他们各自独立工作然后合并工作成果所需要的时间多一倍的思想有关。
如果将软件开发的因素限定为编程的时候我们能够输入有多快,这肯定是对的,但是根据kent beck的观察,如果情况真的如此的话,我们给每个员一份mavis beacon(盲打教学软件)就行了。
我自己不会盲打,我也从来都没有在面试别人的时候问过他们的打字速度,所以打字速度是我们的主要关注因素的想法是值得怀疑的。然而,软件开发是一项智力活动,它能够从清楚的表达和思想的合作发展中受益,而配对编程在这两个方面都有所帮助。
另外一个误解是,配对编程成功与否,应该最终由产出的软件的质量来确定。当两个人合作的时候,至少有三种结果:
这些变化的比例取决于配对的平衡和动态,但是上述所有三者都会在某种程度上表现出来。当一个经验丰富的员与一个新手配对的时候,配对产生的软件可能不会被那个有经验的员单独工作产生的软件更多,但是这个新手肯定会学到很多关于这个应用的知识以及关于编程的基本知识。
将这一情形与两人单独工作相比较——我们可能得到更多的软件(尽管我们可能希望更加注意新手编写的软件的质量),但是我们却没有实现知识或者技能的转移。如果我们让这两个人在同一个小组里,配对编程就是两个人度过共同时光的理想方法。
而另一方面,两个有经验的人可能会发现配对编程里没有什么技能的转移,但是让他们在不同的抽象层次解决同一个问题会让他们更快地找到凯发天生赢家一触即发官网的解决方案,而且错误更少。
配对编程的另一个目标是尽可能广泛地传播应用设计和实现的知识。
这是通过配对轮换实现的,这样小组配对的每个人都可以通过一段时间和其他所有人进行配对,而且应用的特定部分都会由尽可能多的人来解决。在这种环境里,糟糕的代码不会存在太久,因为它被暴露在很多双眼睛下(这就与开发人员代码开发背后的一个原理相似),而且当设计周期到来的时候,小组就会从所有人的贡献里受益,而不需要仅仅依赖某个熟悉应用特定部分的个人。
配对编程还有其他多种好处:
在定期配对轮换的情况下,上面列表里的最后两项尤其现实。当然,做得看起来像配对编程的方式有很多,但是却无法实现,或者破坏了这些优势。
如果不进行配对轮换,那么你所获得只会是编程的小圈子,知识和技术的转移也只会是最小。有些公司将配对编程用作是消灭个人空间(每两个员只需要一张桌子和一台计算机,不是吗?)的理由,这只会忽视员的人类需求。
希望让员一天八个小时都配对工作是不现实的——配对的持续交互带来了精确和清晰的结果,但是这一过程也是耗费精力的,而且(一个人)总是会有开发以外的任务要完成。
实践经验告诉我们,配对编程是提高软件质量和减少开发时间的有效方法,但是它并不适用于所有的员,它需要一种经过仔细思考的方式实现才能有效。
steve hayes是internet business systems(ibs)公司的软件开发经理。ibs公司为金融服务行业提供敏捷开发方法咨询和开发服务,以及浏览器托管凯发天生赢家一触即发官网的解决方案。