UML软件工程组织 |
大型项目的XP(极限编程) |
作者:Amr Elssamadisy 著,simaetin 译 |
本文选自:UMLCHINA 我们在ThoughtWorks这样的大型项目中应用XP方法的时间超过了15个月。这个项目开始于三年前,那时它有大量的需求文档和几个独立的功能小组。从2000年1月起,我们决定应用XP,虽然当时我们已经知道XP并不适用于大型项目。那时,我们需要向客户提交功能演示,并要通过提交一个工作子集而不仅仅是原型来赢得他们的信心(我们在团队中有超过25名开发人员和大约15名分析员)。但我们并未准备好功能,各个组都使用自己的代码框架,一个完整的应用无从谈起。简短地说,就是客户想要看到点什么,但我们还没有真正的功能。应该说开发的第一迭代期是成功的:我们给客户提交了一个真正的应用子集。成功的首要原因是我们让来自Asset,
AR 和GUI组从事不同工作的开发者融合在一起。当然,其间也有"成长的烦恼":在分析员和开发者之间发生某些个人冲突,但我们成功跨越了这些障碍。那时一切都很美好:我们以飞快的速度成功地提交了功能演示,但随着时间的流逝和项目的继续,有些事情却不如我们所愿。这就是这篇文章要讲述的内容:我们真正的收获在"蜜月"期后,关于我们如何在一年半中管理一个50人的项目开发并及时完成阶段性的提交(尽管有时并不成功),关于我们经历的痛苦,我们后续的工作,我们最终学到的以及作为改进要用到下一个项目中的经验。
首先我们说说结对编程的体会。多数情况下,我们在某个迭代期间有两个开发人员同时为一个故事卡片(或几个迭代期的相关卡片)工作。在大型项目中开发人员需要投入更多的关注,因为开始新领域的编码的热身时间是不容忽视的。开发人员间良好的沟通和周期性的计划会议让每个人都具有谁在做什么的整体概念。这使得经典教科书中开发者甲找到开发者乙要求共同解决问题的结对编程方式成为可能。 结对编程当然很好,但并非任何时侯都适用。最通常的情况是,在改错和维护时开发人员并不愿结对,并且这种情况下许多眼睛盯着调试代码也确实没什么好处。再有就是迭代期间的重复工作,这种情况下,问题的解决方案已经确定,不必再结对了。 还有,开发人员有不同的个性:有些人需要间歇性的结对编程,而有些人更加出色,结对编程会妨碍他们才能的发挥而最终成为他们的负担。 单元测试和集成构造绝对是必要的,这意味着如果我们没有测试,我们就不能提交任何代码。当应用程序变得越来越大时,没有测试我们就不能加入任何新功能或进行重构。我们现在在新代码进库时会有集成构造和测试。关于这些构造及测试的细节,负责人员会及时放在内部网页上,这样每个开发人员都能知道当前的构造状态,事务分析员和QA能拿到最近构造的信息来测试新的功能。 对于这样一个大型的项目,为了防止被分为孤立的部分而使整个系统做出不适当的假设,信息的发布和不同部分的代码轮作非常重要。沟通是必需的(但我们无法强迫一个沉默的人开口)于是我们试图在每两周一次的短会上给每个人发言的机会,以使沉默寡言的人能说出他们的要求。而最终我们取消了这样的会议,因为大多数开发人员认为这种把每件事都蜻蜓点水地提一下的会议只是浪费时间。这也是这个团队的优点之一??我们总能象一个共同体般地工作,如同结对编程一样地合作。 开始,我们采用了轮作的方法,也就是每个人对每件事都作一点,这使得我们在后来快到截止期限的时候都在从事己经了解的事情。但对于一段复杂的代码,要做到这一点,时间投入非常巨大。最好采用折衷的办法:也 就是在项目时间紧的时候只作每个人熟悉的工作,而在其它时候,比如改错、研究或正在做一项熟悉的工作时,可以同时做一件不熟悉的事。我们现在的原则是,开发人员在几个迭代周期中连续做一些相关的卡片,同时逐渐地转向系统的其它部分。在同一个迭代期内签入几个不同卡片的做法己经不再用了。 代码确实会越变越糟。是因为我们的项目有些大吗?还是因为许多做代码的人都是新手(是指这个功能领域中的新手,而非编程新手)?答案可能是二者皆有吧。但有时我们不接触代码,很难开始系统的其它部分,因此定期清理代码是必须的。这样引出我们下一个论题:重构。 在应用XP的大型项目中,为了消除代码的不一致性,重构是绝对必要的。即便对于那些对项目的应用领域很熟悉的人,也会面对重构的巨大工作量望而却步。对于项目经理来说,必须认识到重构需要另行分配时间。我们做到了这一点,我们留出了时间来重构代码的主要部分。 迭代期及其期限是必须的,但长度一直是个问题。过去我们采用长迭代周期(如一个月),而每到月末就会很紧张并伴随着一些不良代码的加入,并且不可避免地在估计上出现问题。我们不得不接受一些未做的卡片(这对开发人员来说非常困难,并且难以满足既定的期限)。 下面把18个月中我们在这个50人项目的经验和教训列出如下: 1) 在每个迭代期开始时进行迭代计划会议。每日客户和开发人员讨论最近的故事卡片并评估它们,在每天的讨论结束后重新分组并演示这些评价和发现,然后让开发人员签入。这可以让整个项目组知道项目的当前情况而不用让每个人都卷入马拉松式的会议。 2) 使提交版本周期尽可能短:我们是两周一次,但在必要的时候也可以使提交跨多个迭代周期。允许在多个迭代周期签入卡片,但要以每个周期为单位进行进度的监控。 3) 进行尽可能多的单元测试,这是不言而喻的。应当有一个自动进行功能测试的软件包以保证测试的覆盖范围。但是QA组是不可替代的(无论开发人员写过多少测试程序),因为我们对系统怎样工作总是存在偏见。 4) 简单的设计能帮助我们连续向客户提供可工作的版本。频繁的设计会议对于加入大量新功能时是很有用的,而午餐是一个召集整个项目组的好时候。这可以避免在系统的不同部分同时存在不兼容的解决方案。 5) 重构是能够做到简单设计的唯一方法。设计的重构与代码的重构同等重要。尽管不进行重构而采用打补丁的解决方法往往是有吸引力的,但是如果一个系统的补丁太多,那就意味着今后它将进行更大的重构。 6) 在加入新功能时,要坚定不移地贯彻结对编程,而在改错和做重复性工作时停止,因为问题已经在结对时解决了。 7) 集体所有和沟通密不可分。团队必须有一种有效的沟通方式。也许不仅仅是非正式的讨论,有时定期的10到15分钟的发布会是很好的方式。 8) 在大型项目中,一些人要扮演客户的角色,为大量开发人员产生足够的工作。这和领域知识密切相关。 9) 编码标准是十分非正式的,这不会损害你的进度。更重要的是一种通过演示的沟通。代码不是文档的全部,开发人员需要看到全貌,这是代码不能提供的。 也有一些规则我们没有实行: 1) 两周一次的站立会议是低效的。可以选择每月一次的迭代团队通气会来替代。 2) 迭代计划会议没有必要让全部人员参与。更好的方式是按更小的组进行研讨,而在每天下班前用30到45分钟对卡片进行讨论。 3) 一个月的迭代期太长,不利于产生高质量的代码。2周一次的迭代周期更容易跟踪并使估计更准确。 4) 上一点在大代码量时并不合适,特别是重构大规模系统时。这时一张卡片会影响到多个迭代期。 5) 比喻(Metaphor)对于大型系统是不适合的。 6) 每周40小时我们来说不成问题,40小时是最少的情况,超时工作并没有给我们带来不利的影响。要重申的是,我们不是100%的实行结对编程。 这就是XP,或者说我们的XP版本,在我们小组所做的工作。我们经历了按时提交大型复杂应用的过程,也为每个开发人员提供了应对此类项目的宝贵经验。 1. Beck, K. Extreme Programming Explained: Embrace Change. Addison-Wesley, 1999; ISBN201-61641-6 2. Fowler, M. and Foemmel, M.; Continuous Integration
|
版权所有:UML软件工程组织 |