版权归原作者所有,如有侵权,请联系我们

[科普中国]-极限编程

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

极限编程(ExtremeProgramming,简称XP)是由KentBeck在1996年提出的,是一种软件工程方法学,是敏捷软件开发中可能是最富有成效的几种方法学之一。如同其他敏捷方法学,极限编程和传统方法学的本质不同在于它更强调可适应性而不是可预测性。

KentBeck在九十年代初期与WardCunningham共事时,就一直共同探索着新的软件开发方法,希望能使软件开发更加简单而有效。Kent仔细地观察和分析了各种简化软件开发的前提条件、可能性以及面临的困难。1996年三月,Kent终于在为DaimlerChrysler所做的一个项目中引入了新的软件开发观念——XP。适用于小团队开发。

简介极限编程是一个轻量级的、灵巧的软件开发方法;同时它也是一个非常严谨和周密的方法。它的基础和价值观是交流、朴素、反馈和勇气;即,任何一个软件项目都可以从四个方面入手进行改善:加强交流;从简单做起;寻求反馈;勇于实事求是。

XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期;通过积极的交流、反馈以及其它一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。

极限编程的目标极限编程的主要目标在于降低因需求变更而带来的成本。在传统系统开发方法中,系统需求是在项目开发的开始阶段就确定下来,并在之后的开发过程中保持不变的。这意味着项目开发进入到之后的阶段时出现的需求变更(而这样的需求变更在一些发展极快的领域中是不可避免的)将导致开发成本急速增加。

极限编程透过引入基本价值、原则、方法等概念来达到降低变更成本的目的。一个应用了极限编程方法的系统开发项目在应对需求变更时将显得更为灵活。

极限编程的特征极限编程方法的基本特征是:

增量和反复式的开发----一次小的改进跟着一个小的改进。

反复性,通常是自动重复的单元测试,回归测试。参见JUnit。

结对程序设计

在程序设计团队中的用户交互(在场的客户)

软件重构

共享的代码所有权

简单

反馈

用隐喻来组织系统

可以忍受的速度

相关概念软件开发过程软件开发的过程是:需求分析、设计、编码和测试。

需求分析:不仅仅是用户需求,应该是开发中遇到的所有的需求。比如,你首先要知道做这个项目是为了解决什么问题;测试案例中应该输入什么数据……为了清楚地知道这些需求,你经常要和客户、项目经理等交流。

设计:编码前,肯定有个计划告诉你要做什么,结构是怎样等等。你一定要按照这个来做,否则可能会一团糟。

编码:如果在项目截止日,你的程序不能跑起来或达不到客户的要求,你就拿不到钱。

测试:目的是让你知道,什么时候算是完成了。如果你聪明,你就应该先写测试,这样可以及时知道你是否真地完成了。否则,你经常会不知道,到底有哪些功能是真正完成了,离预期目标还差多远。

权利和义务定义每个用户需求的商业优先级;

制订总体计划,包括用多少投资、经过多长时间、达到什么目的;

在项目开发过程中的每个工作周,都能让投资获得最大的收益;

通过重复运行你所指定的功能测试,准确地掌握项目进展情况;

能随时改变需求、功能或优先级,同时避免昂贵的再投资;能够根据各种变化及时调整项目计划;

能够随时取消项目;项目取消时,以前的开发工作不是一堆垃圾,已开发完的功能是合乎要求的,正在进行或未完成的的工作则应该是不难接手的。

开发人员知道要做什么,以及要优先做什么;

工作有效率;

有问题或困难时,能得到客户、同事、上级的回答或帮助;

对工作做评估,并根据周围情况的变化及时重新评估;

积极承担工作,而不是消极接受分配;

一周40小时工作制,不加班。

其他问题灵巧的轻量级软件开发方法

一套软件开发方法是由一系列与开发相关的规则、规范和惯例。重量级的开发方法严格定义了许多的规则、流程和相关的文档工作。灵巧的轻量级开发方法,其规则和文档相对较少,流程更加灵活,实施起来相对较容易。

在软件工程概念出现以前,程序员们按照自己喜欢的方式开发软件。程序的质量很难控制,调试程序很繁琐,程序员之间也很难读懂对方写的代码。1968年,Edsger Dijkstra给CACM写了一封题为GOTO Statement Considered Harmful的信,软件工程的概念由此诞生。程序员们开始摒弃以前的做法,转而使用更系统、更严格的开发方法。为了使控制软件开发和控制其它产品生产一样严格,人们陆续制定了很多规则和做法,发明了很多软件工程方法,软件质量开始得到大幅度提高。随着遇到的问题更多,规则和流程也越来越精细和复杂。

到了今天,在实际开发过程中,很多规则已经难于遵循,很多流程复杂而难于理解,很多项目中文档的制作过程正在失去控制。人们试图提出更全面更好的一揽子方案,或者寄希望于更复杂的、功能更强大的辅助开发工具(CaseTools),但总是不能成功,而且开发规范和流程变得越来越复杂和难以实施。

为了赶进度,程序员们经常跳过一些指定的流程,很少人能全面遵循那些重量级开发方法。

失败的原因很简单,这个世界没有万能药。因此,一些人提出,将重量级开发方法中的规则和流程进行删减、重整和优化,这样就产生了很多适应不同需要的轻量级流程。在这些流程中,合乎实际需要的规则被保留下来,不必要的复杂化开发的规则被抛弃。而且,和传统的开发方法相比,轻量级流程不再象流水生产线,而是更加灵活。

ExtremeProgramming(XP)就是这样一种灵巧的轻量级软件开发方法。

为什么称为“Extreme”(极限)?

“Extreme”(极限)是指,对比传统的项目开发方式,XP强调把它列出的每个方法和思想做到极限、做到最好;其它XP所不提倡的,则一概忽略(如开发前期的整体设计等)。一个严格实施XP的项目,其开发过程应该是平稳的、高效的和快速的,能够做到一周40小时工作制而不拖延项目进度。

核心价值极限编程中有四个核心价值是我们在开发中必须注意的:

沟通(Communication)、简单(Simplicity)、反馈(Feedback)、勇气(Courage)、此外还扩展了第五个价值观:尊重(Respect)。

XP用“沟通、简单、反馈、勇气和尊重”来减轻开发压力和包袱;无论是术语命名、专著叙述内容和方式、过程要求,都可以从中感受到轻松愉快和主动奋发的态度和气氛。这是一种帮助理解和更容易激发人的潜力的手段。XP用自己的实践,在一定范围内成功地打破了软件工程“必须重量”才能成功的传统观念。

XP精神可以启发我们如何学习和对待快速变化、多样的开发技术。成功学习XP的关键,是用“沟通、简单、反馈、勇气和尊重”的态度来对待XP;轻松愉快地来感受XP的实践思想;自己认真实践后,通过对真实反馈的分析,来决定XP对自己的价值;有勇气接受它,或改进它。1

价值极限编程技术以沟通、简单、反馈、勇气和尊重为价值标准1。

沟通构建一个软件系统的基本任务之一就是与系统的开发者交流以明确系统的具体需求。在一些正式的软件开发方法中,这一任务是通过文档来完成的。

极限编程技术可以被看成是在开发小组的成员之间迅速构建与传播制度上的认识的一种方法。它的目标是向所有开发人员提供一个对于系统的共享的视角,而这一视角又是与系统的最终用户的视角相吻合的。为了达到这一目标,极限编程支持设计、抽象、还有用户-程序员间交流的简单化,鼓励经常性的口头交流与回馈。

简单极限编程鼓励从最简单的解决方式入手再通过不断重构达到更好的结果。这种方法与传统系统开发方式的不同之处在于,它只关注于对当前的需求来进行设计、编码,而不去理会明天、下周或者下个月会出现的需求。极限编程的拥护者承认这样的考虑是有缺陷的,即有时候在修改现有的系统以满足未来的需求时不得不付出更多的努力。然而他们主张“不对将来可能的需求上投入精力”所得到的好处可以弥补这一点,因为将来的需求在他们还没提出之前是很可能发生变化的。为了将来不确定的需求进行设计以及编码意味着在一些可能并不需要的方面浪费资源。而与之前提到的“交流”这一价值相关联来看,设计与代码上的简化可以提高交流的质量。一个由简单的编码实现的简单的设计可以更加容易得被小组中的每个程序员所理解。

反馈在极限编程中,“反馈”是和系统开发的很多不同方面相关联的:

来自系统的反馈:通过编写单元测试,程序员能够很直观的得到经过修改后系统的状态。

来自客户的反馈:功能性测试是由客户还有测试人员来编写的。他们能由此得知当前系统的状态。这样的评审一般计划2、3个礼拜进行一次,这样客户可以非常容易的了解、掌控开发的进度。

来自小组的反馈:当客户带着新需求来参加项目计划会议时,小组可以直接对于实现新需求所需要的时间进行评估然后反馈给客户2。

反馈是与“交流”、“简单”这两条价值紧密联系的。为了沟通系统中的缺陷,可以通过编写单元测试,简单的证明某一段代码存在问题。来自系统的直接反馈信息将提醒程序员注意这一部分。用户可以以定义好的功能需求为依据,对系统进行周期性的测试。用Kent Beck的话来说:“编程中的乐观主义是危险的,而及时反馈则是解决它的方法。”

勇气极限编程理论中的“系统开发中的勇气”最好用一组实践来诠释。其中之一就是“只为今天的需求设计以及编码,不要考虑明天”这条戒律。这是努力避免陷入设计的泥潭、而在其他问题上花费了太多不必要的精力。勇气使得开发人员在需要重构他们的代码时能感到舒适。这意味着重新审查现有系统并完善它会使得以后出现的变化需求更容易被实现。另一个勇气的例子是了解什么时候应该完全丢弃现有的代码。每个程序员都有这样的经历:他们花了一整天的时间纠缠于自己设计和代码中的一个复杂的难题却无所得,而第二天回来以一个全新而清醒的角度来考虑,在半小时内就轻松解决了问题。

开发工作环境为了在软件开发过程中最大程度地实现和满足客户和开发人员的基本权利和义务,XP要求把工作环境也做得最好。每个参加项目开发的人都将担任一个角色(项目经理、项目监督人等等)并履行相应的权利和义务。所有的人都在同一个开放的开发环境中工作,最好是所有人在同一个大房子中工作,还有茶点供应;每周40小时,不提倡加班;每天早晨,所有人一起站着开个短会;墙上有一些大白板,所有的Story卡、CRC卡等都贴在上面,讨论问题的时候可以在上面写写画画;下班后大家可以一起玩电脑游戏……

需求客户应该是项目开发队伍中的一员,而不是和开发人员分开的;因为从项目的计划到最后验收,客户一直起着很重要的作用。开发人员和客户一起,把各种需求变成一个个小的用户故事(UserStory),例如“计算年级的总人数,就是把该年级所有班的人数累加。”;这些模块又会根据实际情况被组合在一起或者被分解成更小的模块;它们都被记录在一些故事卡(StoryCard)上,之后分别被程序员们在各个小的迭代中(Iteration,通常不超过3个星期)实现;客户根据每个模块的商业价值来指定它们的优先级;开发人员要做的是确定每个需求模块的开发风险,风险高的(通常是因为缺乏类似的经验)需求模块将被优先研究、探索和开发;经过开发人员和客户分别从不同的角度评估每个模块后,它们被安排在不同的开发周期里,客户将得到一个尽可能准确的开发计划;客户为每个需求模块指定验收测试(功能测试)。

每发布一次开发的软件(经过一个开发周期),用户都能得到一个可以开始使用的系统,这个系统全面实现了相应的计划中的所有需求。而在一些传统的开发模式中,无论什么功能,用户都要等到所有开发完成后才能开始使用。

设计从具体开发的角度来看,XP内层的过程是一个个基于测试驱动开发(TestDrivenDevelopment)周期,诸如计划和设计等外层的过程都是围绕这些展开的。每个开发周期都有很多相应的单元测试(UnitTest)。刚开始,因为什么都没有实现,所以所有的单元测试都是失败的;随着一个个小的需求模块的完成,通过的单元测试也越来越多。通过这种方式,客户和开发人员都很容易检验,是否履行了对客户的承诺。XP提倡对于简单的设计(SimpleDesign),就是用最简单的方式,使得为每个简单的需求写出来的程序可以通过所有相关的单元测试。XP强调抛弃那种一揽子详细设计方式(BigDesignUpFront),因为这种设计中有很多内容是你现在或最近都根本不需要的。XP还大力提倡设计走查(Review)、代码走查以及重构(Refectory),所有的这些过程其实也是优化设计的过程;在这些过程中不断运行单元测试和功能测试,可以保证经过重整和优化后的系统仍然符合所有需求。

编程既然编程很重要,XP就提倡结对编程(PairProgramming),而且代码所有权是归于整个开发队伍(CollectiveCodeOwnership)。程序员在写程序和重构程序的时候,都要严格遵守编程规范。任何人都可以修改其他人写的程序,修改后要确定新程序能通过单元测试。结对编程的好处是,一个人编写代码时另一个人在思考。思考者的头脑中保持总体概念,不仅手头问题的这一段,而且还有XP指导方针。例如,如果两个人都在工作,就不太可能会有其中一个说“我不想首先写测试”而离开。如果编码者遇到障碍,他们就交换位置。如果两个人都遇到障碍,他们的讨论可能被在这个区域工作的其他人听到,可能给出帮助。这种结对方式,使事情顺畅、有章可循。也许更重要的是,他能使程序设计更具有社交性和娱乐性。

测试既然测试很重要,XP就提倡在开始写程序之前先写单元测试。开发人员应该经常把开发好的模块整合到一起(ContinuousIntegration),每次整合后都要运行单元测试;做任何的代码走查和修改,都要运行单元测试;发现了BUG,就要增加相应的测试(因此XP方法不需要BUG数据库)。除了单元测试之外,还有集成测试,功能测试、压力测试和系统测试等。所有这些测试,是XP开发过程中最重要的文档之一,也是最终交付给用户的内容之一2。

方法基于敏捷的核心思想和价值目标,XP要求项目团队遵循13个核心实践

团队协作(Whole Team)

规划策略(The Planning Game);

结对编程(Pair programming)

测试驱动开发(Testing-Driven Development)

重构(Refactoring)

简单设计(Simple Design)

代码集体所有权(Collective Code Ownership)

持续集成(Continuous Integration)

客户测试(Customer Tests)

小型发布(Small Release)

每周40小时工作制(40-hour Week)

编码规范(Code Standards)

系统隐喻(System Metaphor)

极限编程的4个商业实践:

测试驱动开发—TDD是你的商业安全网。因为测试是在编码之前完成的,所以写完的测试一定会运行失败,接下来再写代码使测试可以通过。TDD保证你的产品功能,不管公司和技术团队实现的是大规模的变更还是小规模的变更。

结对编程—让2名开发人员写同一段代码,使用同一个键盘和同一台显示器。因为结对大大降低了浪费的时间和缺陷,所以能带来更高质量的代码,并带来高水平的协作。

集体代码所有制和持续集成—如果每段代码不只有一个人熟悉,那么就不会有什么交流瓶颈了。把代码持续集成到一个主干可以避免重复和不匹配的代码。

重构—在当时的情况下,写的代码是解决已知问题的。通常,团队巧妙地解决了他们的问题,然后持续重构和修改代码,确保代码库能以最为高效的方式不断满足业务最新的需要。

规则项目开发小组在XP中,每个对项目做贡献的人都应该是项目开发小组中的一员。而且,这个小组中必须至少有一个人对用户需求非常清晰,能够提出需求、决定各个需求的商业价值(优先级)、根据需求等的变化调整项目计划等。这个人扮演的是“客户”这个角色,当然最好就是实际的最终用户,因为整个项目就是围绕最终用户的需求而展开的。程序员是项目开发小组中必不可少的成员。小组中可以有测试员,他们帮助客户制订验收测试;有分析员,帮助客户确定需求;通常还有个Coach(教练),负责跟踪开发进度、解决开发中遇到的一些问题、推动项目进行;还可以有一个项目经理,负责调配资源、协助项目内外的交流沟通等等。项目小组中有这么多角色,但并不是说,每个人做的工作是别人不能插手或干预的,XP鼓励每个人尽可能地为项目多做贡献。平等相处,取长补短;这就是最好的XP开发小组。

过程计划项目(PlanningGame)、验收测试、小规模发布(SmallReleases)

XP开发小组使用简单的方式进行项目计划和开发跟踪,并以此预测项目进展情况和决定未来的步骤。根据需求的商业价值,开发小组针对一组组的需求进行一系列的开发和整合,每次开发都会产生一个通过测试的、可以使用的系统。

计划项目XP的计划过程主要针对软件开发中的两个问题:预测在交付日期前可以完成多少工作;现在和下一步该做些什么。不断的回答这两个问题,就是直接服务于如何实施及调整开发过程;与此相比,希望一开始就精确定义整个开发过程要做什么事情以及每件事情要花多少时间,则事倍功半。针对这两个问题,XP中又两个主要的相应过程:

软件发布计划(ReleasePlanning)。客户阐述需求,开发人员估算开发成本和风险。客户根据开发成本、风险和每个需求的重要性,制订一个大致的项目计划。最初的项目计划没有必要(也没有可能)非常准确,因为每个需求的开发成本、风险及其重要性都不是一成不变的。而且,这个计划会在实施过程中被不断地调整以趋精确。

周期开发计划(IterationPlanning)。开发过程中,应该有很多阶段计划(比如每三个星期一个计划)。开发人员可能在某个周期对系统进行内部的重整和优化(代码和设计),而在某个周期增加了新功能,或者会在一个周期内同时做两方面的工作。但是,经过每个开发周期,用户都应该能得到一个已经实现了一些功能的系统。而且,每经过一个周期,客户就会再提出确定下一个周期要完成的需求。在每个开发周期中,开发人员会把需求分解成一个个很小的任务,然后估计每个任务的开发成本和风险。这些估算是基于实际开发经验的,项目做得多了,估算自然更加准确和精确;在同一个项目中,每经过一个开发周期,下一次的估算都会有更多的经验、参照和依据,从而更加准确。这些简单的步骤对客户提供了丰富的、足够的信息,使之能灵活有效地调控开发进程。每过两三个星期,客户总能够实实在在地看到开发人员已经完成的需求。在XP里,没有什么“快要完成了”、“完成了90%”的模糊说法,要不是完成了,要不就是没完成。这种做法看起来好像有利有弊:好处是客户可以马上知道完成了哪些、做出来的东西是否合用、下面还要做些什么或改进什么等等;坏处是客户看到做出来的东西,可能会很不满意甚至中止合同。实际上,XP的这种做法是为了及早发现问题、解决问题,而不是等到过了几个月,用户终于看到开发完的系统了,然后才告诉你这个不行、那个变了、还要增加哪个内容等等。

验收测试客户对每个需求都定义了一些验收测试。通过运行验收测试,开发人员和客户可以知道开发出来的软件是否符合要求。XP开发人员把这些验收测试看得和单元测试一样重要。为了不浪费宝贵的时间,最好能将这些测试过程自动化。

频繁地小规模发布软件(SmallReleases)

每个周期(Iteration)开发的需求都是用户最需要的东西。在XP中,对于每个周期完成时发布的系统,用户都应该可以很容易地进行评估,或者已经能够投入实际使用。这样,软件开发对于客户来说,不再是看不见摸不着的东西,而是实实在在的。XP要求频繁地发布软件,如果有可能,应该每天都发布一个新版本;而且在完成任何一个改动、整合或者新需求后,就应该立即发布一个新版本。这些版本的一致性和可靠性,是靠验收测试和测试驱动的开发来保证的。

简单设计XP中让初学者感到最困惑的就是这点。XP要求用最简单的办法实现每个小需求,前提是按照这些简单设计开发出来的软件必须通过测试。这些设计只要能满足系统和客户在当下的需求就可以了,不需要任何画蛇添足的设计,而且所有这些设计都将在后续的开发过程中就被不断地重整和优化。

在XP中,没有那种传统开发模式中一次性的、针对所有需求的总体设计。在XP中,设计过程几乎一直贯穿着整个项目开发:从制订项目的计划,到制订每个开发周期(Iteration)的计划,到针对每个需求模块的简捷设计,到设计的复核,以及一直不间断的设计重整和优化。整个设计过程是个螺旋式的、不断前进和发展的过程。从这个角度看,XP是把设计做到了极致。

PairProgramming

XP中,所有的代码都是由两个程序员在同一台机器上一起写的——这是XP中让人争议最多、也是最难实施的一点。这保证了所有的代码、设计和单元测试至少被另一个人复核过,代码、设计和测试的质量因此得到提高。看起来这样象是在浪费人力资源,但是各种研究表明事实恰恰相反。——这种工作方式极大地提高了工作强度和工作效率。

很多程序员一开始是被迫尝试这点的(XP也需要行政命令的支持)。开始时总是不习惯的,而且两个人的效率不会比一个人的效率高。这种做法的效果往往要坚持几个星期或一两个月后才能很显著。据统计,在所有刚开始PairProgramming的程序员中,90%的人在两个月以后都很认为这种工作方式更加高效。

项目开发中,每个人会不断地更换合作编程的伙伴。因此,PairProgramming不但提高了软件质量,还增强了相互之间的知识交流和更新,增强了相互之间的沟通和理解。这不但有利于个人,也有利于整个项目、开发队伍和公司。从这点看,PairProgramming不仅仅适用于XP,也适用于所有其它的软件开发方法。

测试驱动反馈是XP的四个基本的价值观之一——在软件开发中,只有通过充分的测试才能获得充分的反馈。XP中提出的测试,在其它软件开发方法中都可以见到,比如功能测试、单元测试、系统测试和负荷测试等;与众不同的是,XP将测试结合到它独特的螺旋式增量型开发过程中,测试随着项目的进展而不断积累。另外,由于强调整个开发小组拥有代码,测试也是由大家共同维护的。即,任何人在往代码库中放程序(CheckIn)前,都应该运行一遍所有的测试;任何人如果发现了一个BUG,都应该立即为这个BUG增加一个测试,而不是等待写那个程序的人来完成;任何人接手其他人的任务,或者修改其他人的代码和设计,改动完以后如果能通过所有测试,就证明他的工作没有破坏原系统。这样,测试才能真正起到帮助获得反馈的作用;而且,通过不断地优先编写和累积,测试应该可以基本覆盖全部的客户和开发需求,因此开发人员和客户可以得到尽可能充足的反馈。

重构XP强调简单的设计,但简单的设计并不是没有设计的流水账式的程序,也不是没有结构、缺乏重用性的程序设计。开发人员虽然对每个USERSTORY都进行简单设计,但同时也在不断地对设计进行改进,这个过程叫设计的重构(Refactoring)。这个名字最早出现在MartinFowler写的《Refactoring:Improving the Design of Existing Code》这本书中。

Refactoring主要是努力减少程序和设计中重复出现的部分,增强程序和设计的可重用性。Refactoring的概念并不是XP首创的,它已经被提出了近30年了,而且一直被认为是高质量的代码的特点之一。但XP强调,把Refactoring做到极致,应该随时随地、尽可能地进行Refactoring,只要有可能,程序员都不应该心疼以前写的程序,而要毫不留情地改进程序。当然,每次改动后,程序员都应该运行测试程序,保证新系统仍然符合预定的要求。

XP开发小组经常整合不同的模块。为了提高软件质量,除了测试驱动开发和PairProgramming以外,XP要求每个人的代码都要遵守编程规范,任何人都可以修改其他人写的代码,而且所有人都应该主动检查其他人写的代码。

频繁地整合在很多项目中,开发人员往往很迟才把各个模块整合在一起。在这些项目中,开发人员经常在整合过程中发现很多问题,但不能肯定到底是谁的程序出了问题;而且,只有整合完成后,开发人员才开始稍稍使用整个系统,然后就马上交付给客户验收。对于客户来说,即使这些系统能够通过终验收测试,因为使用时间短,客户门心里并没有多少把握。

为了解决这些问题,XP提出,整个项目过程中,应该频繁地,尽可能地整合已经开发完的USERSTORY(每次整合一个新的USERSTORY)。每次整合,都要运行相应的单元测试和验收测试,保证符合客户和开发的要求。整合后,就发布一个新的应用系统。这样,整个项目开发过程中,几乎每隔一两天,都会发布一个新系统,有时甚至会一天发布好几个版本。通过这个过程,客户能非常清楚地掌握已经完成的功能和开发进度,并基于这些情况和开发人员进行有效地、及时地交流,以确保项目顺利完成。

集体拥有代码在很多项目开发过程中,开发人员只维护自己的代码,而且很多人不喜欢其他人随意修改自己的代码。因此,即使可能有相应的比较详细的开发文档,但一个程序员却很少、也不太愿意去读其他程序员的代码;而且,因为不清楚其他人的程序到底实现了什么功能,一个程序员一般也不敢随便改动其他人的代码。同时,因为是自己维护自己的代码,可能因为时间紧张或技术水平的局限性,某些问题一直不能被发现或得到比较好的解决。针对这点,XP提倡大家共同拥有代码,每个人都有权利和义务阅读其他代码,发现和纠正错误,重整和优化代码。这样,这些代码就不仅仅是一两个人写的,而是由整个项目开发队伍共同完成的,错误会减少很多,重用性会尽可能地得到提高,代码质量是非常好。

为了防止修改其他人的代码而引起系统崩溃,每个人在修改后都应该运行测试程序。(从这点,我们可以再次看到,XP的各个惯例和规则是怎样有机地结合在一起的。)

编程规范XP开发小组中的所有人都遵循一个统一的编程标准,因此,所有的代码看起来好像是一个人写的。因为有了统一的编程规范,每个程序员更加容易读懂其他人写的代码,这是实现CollectiveCodeOwnership的重要前提之一。

每周40小时工作制(40-hour Week),不加班

XP过程通过使用一些形象的比喻让所有人对系统有个共同的、简洁的认识。XP认为加班是不正常的,因为这说明关于项目进度的估计和安排有问题。

Metaphor(系统比喻)

为了帮助每个人一致清楚地理解要完成的客户需求、要开发的系统功能,XP开发小组用很多形象的比喻来描述系统或功能模块是怎样工作的。比如,对于一个搜索引擎,它的Metaphor可能就是“一大群蜘蛛,在网上四处寻找要捕捉的东西,然后把东西带回巢穴。”

其他相关大量的加班意味着原来的计划是不准确的,或者是程序员不清楚自己到底什么时候能完成什么工作。而且,开发管理人员和客户也因此无法准确掌握开发速度;开发人员也因此非常疲劳。XP认为,如果出现大量的加班现象,开发管理人员(比如Coach)应该和客户一起确定加班的原因,并及时调整项目计划、进度和资源。

XP中一些基本概念的简介

UserStory:开发人员要求客户把所有的需求写成一个个独立的小故事,每个只需要几天时间就可以完成。开发过程中,客户可以随时提出新的UserStory,或者更改以前的UserStory。

StoryEstimates和开发速度:开发小组对每个UserStory进行估算,并根据每个开发周期(Iteration)中的实际情况反复计算开发速度。这样,开发人员和客户能知道每个星期到底能开发多少UserStory。

ReleasePlan和ReleaseScope:整个开发过程中,开发人员将不断地发布新版本。开发人员和客户一起确定每个发布所包含的UserStory。

Iteration(开发周期,或称迭代)和IterationPlan:在一个Release过程中,开发人员要求客户选择最有价值的UserStory作为未来一两个星期的开发内容。

TheSeed:第一个迭代(Iteration)完成后,提交给客户的系统。虽然这不是最终的产品,但它已经实现了几个客户认为是最重要的Story,开发人员将逐步在其基础上增加新的模块。

ContinuousIntegration(整合):把开发完的UserStory的模块一个个拼装起来,一步步接近乃至最终完成最终产品。

验收测试(功能测试):对于每个UserStory,客户将定义一些测试案例,开发人员将使运行这些测试案例的过程自动化。

UnitTest(单元测试):在开始写程序前,程序员针对大部分类的方法,先写出相应的测试程序。

Refactoring(重构):去掉代码中的冗余部分,增加代码的可重用性和伸缩性。

影响通过软件工程设计的简单而优美的软件并不比那些设计复杂而难以维护的软件有价值。这是真的吗?XP认为事实并非如此。 一个典型的项目花在人力上的金钱是花在硬件上的时间的20 倍,这意味着一个项目每年要花200 万美元在程序员身上,而仅仅花10 万美元在电脑设备上。很多聪明的程序员说:“我们如此聪明,发现一种方法可以节省20%的硬件开销”,然后他们使得源程序大而且难懂和难以维护,他们会说:“但是我们节省了20%或者2 万美元每年,很大的节省”。反之,如果我们写我们的程序简单而且容易扩展,我们将至少节省10%的人力开销,一笔更大的节省,这是你客户一定会注意到的一些事情。

另外一个对客户来说很重要的问题就是程序的BUGS 。XP 不只是强调测试,而且要求正确的测试。测试必须是能自动进行的,以便为程序和客户提供一个安全的环境。在编码的所有阶段,我们不断增加测试用例。当找到bug 时,我们就添加新的测试,一个紧密的安全网就这样产生了。同一个BUG 不出现两次,这些一定会引起用户的注意。你的客户必须注意的另外一件事情:XP 开发者拥抱需求变化。XP 使我们能够接受需求的变化。

一般情况下,客户只有在系统被开发完成以后能真正去体会它。XP 却不一样,它通过加强客户的反馈来缩短开发的周期,同时获得足够的时间来改变功能和获得用户的认同。在XP 中,你的客户应该明确的知道这一点。

XP开发过程的大多的革命是在软件开发的方法上,代码质量的重要程度超出人们一般所认为的。仅仅因为我们的客户不能明白我们的源代码并不意味着我们可以不努力去管理代码的质量。

使用XP方法的产生是因为难以管理的需求变化,从一开始你的客户并不是很完全的知道他们要的系统是怎么样的,你可能面对的系统的功能一个月变化多次。在大多数软件开发环境中不断变化的需求是唯一的不变,这个时候应用XP 就可以取得别的方法不可能取得的成功。XP 方法的建立同时也是为了解决软件开发项目中的风险问题。假如你的客户在特定的时间内,需要一个相当难开发的系统,而且对于你的项目组来说,这个系统是一个新的挑战(从来没有做过),那风险就更大了,如果这个系统对于整个软件行业来说都是新的挑战,那么它的风险就更大了,采用XP 将可以减少风险,增加成功的可能。 XP方法是为小团体开发建立的,在2-10 个人之间。假如你的团体恰好合适,你就不需要用其他的软件工程方法了,就用XP ,但是要注意你不能将XP 方法应用于大团体的开发项目中。我们应该注意,在需求一惯呈动态变化或者高具有高风险的项目中,你就会发现XP 方法在小团体的开发中的作用要远远高于在大团体的开发。

XP方法需要一个扩展的开发团体,XP 团体不仅仅包括开发者,经理、客户也是其中的一员,所有的工作一环扣一环,问问题,商讨方法和日程,增加功能测试,这些问题的解决不仅仅涉及到软件的开发者。

另一个需要是可测试性,你必须能增加自动的单元测试和功能测试,然而在你进行这个需求的时候,你会发现有许多的问题很难测试,这需要充分发挥你的测试的经验和智慧,而且你有时还要改变你的设计以便它可以更容易的进行测试。记住:那儿有需求,那儿就应该有测试的方法。

在XP方法的好处的清单上,最后一条是生产力。在同样的合作环境下,XP 项目都一致的表现出比使用其他方法高的多的生产力。但这从来不是XP 方法学的真正目标。XP 真实追求的目标是:在规定的时间生产出满足客户需要的软件。假如对于你的开发来说,这是很重要的方面,你就可以选择XP 了。

实践1、完整团队

XP项目的所有参与者(开发人员、客户、测试人员等)一起工作在一个开放的场所中,他们是同一个团队的成员。这个场所的墙壁上随意悬挂着大幅的、显著的图表以及其他一些显示他们进度的东西。

2、计划游戏

计划是持续的、循序渐进的。每2周,开发人员就为下2周估算候选特性的成本,而客户则根据成本和商务价值来选择要实现的特性。

3、客户测试

作为选择每个所期望的特性的一部分,客户可以根据脚本语言来定义出自动验收测试来表明该特性可以工作。

4、简单设计

团队保持设计恰好和当前的系统功能相匹配。它通过了所有的测试,不包含任何重复,表达出了编写者想表达的所有东西,并且包含尽可能少的代码。

5、结对编程

所有的产品软件都是由两个程序员、并排坐在一起在同一台机器上构建的。

6、测试驱动开发

编写单元测试是一个验证行为,更是一个设计行为。同样,它更是一种编写文档的行为。编写单元测试避免了相当数量的反馈循环,尤其是功能验证方面的反馈循环。程序员以非常短的循环周期工作,他们先增加一个失败的测试,然后使之通过。

7、改进设计

随时利用重构方法改进已经腐化的代码,保持代码尽可能的干净、具有表达力。

8、持续集成

团队总是使系统完整地被集成。一个人拆入(Check in)后,其它所有人责任代码集成。

9、集体代码所有权

任何结对的程序员都可以在任何时候改进任何代码。没有程序员对任何一个特定的模块或技术单独负责,每个人都可以参与任何其它方面的开发。

10、编码标准

系统中所有的代码看起来就好像是被单独一人编写的。

11、隐喻

将整个系统联系在一起的全局视图;它是系统的未来影像,是它使得所有单独模块的位置和外观变得明显直观。如果模块的外观与整个隐喻不符,那么你就知道该模块是错误的。

12、可持续的速度

团队只有持久才有获胜的希望。他们以能够长期维持的速度努力工作,他们保存精力,他们把项目看作是马拉松长跑,而不是全速短跑。

小结XP的一个成功因素是重视客户的反馈——开发的目的就是为了满足客户的需要。XP方法使开发人员始终都能自信地面对客户需求的变化。XP强调团队合作,经理、客户和开发人员都是开发团队中的一员。团队通过相互之间的充分交流和合作,使用XP这种简单但有效的方式,努力开发出高质量的软件。XP的设计简单而高效;程序员们通过测试获得客户反馈,并根据变化修改代码和设计,他们总是争取尽可能早地将软件交付给客户。XP程序员能够勇于面对需求和技术上的变化。

XP很象一个由很多小块拼起来的智力拼图,单独看每一小块都没有什么意义,但拼装好后,一幅美丽的图画就会呈现在你面前。

本词条内容贡献者为:

吴晨涛 - 副研究员 - 上海交通大学