项目目前国内对于XP方面的研究和应用此起彼伏,各种关于XP的书籍争相出版,对于以XP为代表的"敏捷软件工程"方法的争论也在网络上随处可见。之所以出现这样的情况,是因为国内的用户在软件项目的实施过程中遇到了很多问题,例如项目的交付时间推迟、用户需求变更频繁等,我们的软件工程师迫切的希望能够找到解决问题的"银弹"。对于高度动态、通过非常短的迭代周期来应对需求变化的极限编程方法论来讲,确实能够从一定程度上解决问题。但是,对于国内的软件开发项目来说,XP并非"银弹",它的一些最佳实践不是都适合国内的情况。本文结合一个具体的软件开发项目,讨论一下XP 在国内的应用情况。
XP简介
传统软件开发方法
在最近的数十年中,很多企业的CEO们都面临着增加盈利的压力,因此,他们采用各种方法,例如裁员、业务外包、BPR、ERP、CRM等等。以上种种,使得世界500强的大部分企业在20世纪90年代的后期一直保持者二位数的利润增长。但是很多迹象表明,在传统的企业业务模型中已经没有多少可供削减开支的地方,因此,需要进行彻底的改革。在软件开发领域,情况更是如此。
自上个世纪60年代以来,软件工程思想逐渐形成与发展,也出现了很多软件开发模型与方法,例如瀑布模型、快速原型、增量模型和螺旋模型等[1]。而在90年代以后,卡耐基梅隆软件学院推出的CMM,更是对于软件开发的过程管理,提出了确切的衡量指标。但是,最近的研究表明,有50%的项目会拖延交付,有30%以上的项目会超出预算,软件开发领域的项目情况比软件工程刚刚提出的时候相比,只是有很小的提高。详细的数据[4](数据来自美国GSM研究机构, Michael Mah)如下表所示:
传统的软件开发过程,以RUP为代表,强调项目的可控性,是一个用例驱动的基于UML和构件式架构的迭代增量式开发过程。RUP定义了初始、细化、实现和部署4个阶段,分别对应着关键里程碑的划分。RUP对于角色、流程、工件和活动的要求是灵活、可配置的,所以它广泛的适用于各种类型的项目。但是,在RUP的各个流程碑,都规定了要交付的成果,尤其是对于需求的变更以及文档,它强调及时的更新与同步。以上这些都决定了RUP是一种重量级的软件开发方法,比较适合大中型的项目和产品开发。
XP以及其核心价值
最近,出现了很多轻量型的软件开发方法,例如水晶模型、适应模型以及极限编程等。它们都强调,软件开发是人与人合作进行的过程,因此成功的软件开发过程应该充分利用人的优势,而弱化人的缺点,突出了人在软件开发过程中的作用[2]。
Kent Beck在XP的开篇之作《Extreme Programming Explained - Embrace Change》中提出了极限编程这一创新的软件过程方法论。极限编程是一种高度动态的过程,它通过非常短的迭代周期来应对需求的变化。在极限编程中,包括四个基本活动:编码、测试、聆听与反馈,XP项目的状态变迁如下图所示[3][4]:
Kent Beck指出,XP有四个核心价值是我们应该注意的[3][4]:
沟通:项目中发现的问题往往是由于开发人员与设计人员、设计人员与客户之间的沟通不畅造成的,因此,在XP项目中没有沟通是不可能的。
简单:XP认为应该尽量保持代码的简单,只要它能工作就可以。Kent Beck指出与其实现一个复杂的的系统,不如设计一个能够满足目前需要的、简单的系统,因为你所考虑的情况可能永远都不会发生。
反馈:尽快获得用户的反馈,并且越详细越好,使得开发人员能够保证自己的成果符合用户的需要。
勇气:这是最重要的核心价值。因为XP强调要"拥抱变化",因此对于用户的反馈,要勇于对自己的代码进行修改,丢掉坏的代码。
下面我们将要谈到的XP的最佳实践就体现了上述四个核心价值。实际上,XP中并没有多少新的观点,它的一些最佳实践也都是长久以来都在使用中的。
XP的适用环境
从XP项目状态图以及它的核心价值中我们可以看到,XP弱化针对未来需求的设计,非常注重当前的简化。它的实践,有一个非常关键的假设就是开发人员只注重眼前需求而依赖重构来适应需求的变动所带来的风险与开销要小于需求变化使得事先充分设计失效的代价;反之,实施XP就是不明智的[5]。
因此,XP适合规模小、进度紧、需求变化大、质量要求严的项目。它希望以最高的效率和质量来解决用户目前的问题,以最大的灵活性和最小的代价来满足用户未来的需求,XP在平衡短期和长期利益之间做了巧妙的选择。
我们可以看到,XP并不是解决问题的"银弹",它也有不适合的情况。Beck曾经建议在以下情况下不宜采用XP:
中大型的项目(项目团队超过10人);
重构会导致大量开销的应用;
需要很长的编译或者测试周期的系统;
不容易进行测试的应用;
团队人员异地分布的项目;
不能接收XP文化的组织和团队;
项目概况及背景
我们公司是亚洲领先的电子商务解决方案供应商,在J2EE架构的项目执行方面有丰富的经验,结合RUP形成了自己的一套电子商务项目实施方法论,并在多个项目中成功进行实施。同时,由于具体项目时间和成本的限制,也出现了许多问题,主要有以下两点:
项目交付后,用户提出很多的修改意见,有些甚至涉及系统架构的修改:出现这种情况的主要原因是很多项目虽然是采用增量迭代式的开发周期,但是在部署前才发布版本,用户只是在项目部署后才看到真正的系统,因此会发现很多界面、流程等方面的问题;
对于用户提交BUG的修改周期过长:开发人员在作开发的时候,对于单元测试的重视程度不够,模块开发结束后就提交给测试人员进行测试,而测试人员由于时间的关系,并不能发现所有的问题;在用户提交BUG后,开发人员由于项目接近尾声,对于代码的修改产生惰性,同时又没有形成有效的回归测试方法,因此,修改的周期比较长。
针对XP的核心价值,可以看到,如果我们能够加强与用户的沟通、增加项目中测试实施的力度、提高开发人员的勇气,就可以从一定程度上解决上述问题。
从2001年开始,公司内部展开对于XP等敏捷方法的研究,希望能够借鉴一些做法,来完善项目方法论。
2002年5月,我们决定在公司的一个新的项目中启用XP的一些最佳实践,来检验其效果。该项目是为一家国际知名手机生产厂商的合作伙伴提供手机配件定购、申请、回收等服务,项目的情况如下表所示:
从上表中可以看出,该项目是一个小型项目,而且项目小组成员对于XP在项目开始之前都有一定的了解,另一方面,客户要求的项目周期比我们预期估计的时间有一定的余地,因此我们决定利用这个项目进行XP的试验性实践。
XP的最佳实践以及在项目中的应用
在项目执行过程中,我们基本上还是采用RUP的软件过程,而没有死板的套用XP 的做法,例如:在需求分析阶段,我们还是采用Use Case来对需求进行描述,而不是XP规定的CRC卡片;在系统分析与设计阶段,首先进行系统的架构设计,而不是简单的套用XP的"简单设计"实践。
下面我们结合项目的具体情况,讨论一下XP的12个最佳实践。
现场客户 ( On-site Customer )
XP: 要求至少有一名实际的客户代表在整个项目开发周期在现场负责确定需求、回答团队问题以及编写功能验收测试。
评述:现场用户可以从一定程度上解决项目团队与客户沟通不畅的问题,但是对于国内用户来讲,目前阶段还不能保证有一定技术层次的客户常驻开发现场。解决问题的方法有两种:一是可以采用在客户那里现场开发的方式;二是采用有效的沟通方式。
项目:首先,我们在项目合同签署前,向客户进行项目开发方法论的介绍,使得客户清楚项目开发的阶段、各个阶段要发布的成果以及需要客户提供的支持等;其次,由项目经理每周向客户汇报项目的进展情况,提供目前发布版本的位置,并提示客户系统相应的反馈与支持。
代码规范 ( Code Standards )
? XP: 强调通过指定严格的代码规范来进行沟通,尽可能减少不必要的文档。
? 评述: XP对于代码规范的实践,具有双重含义:一是希望通过建立统一的代码规范,来加强开发人员之间的沟通,同时为代码走查提供了一定的标准;二是希望减少项目开发过程中的文档,XP认为代码是最好的文档。
对于目前国内的大多数项目团队来说,建立有效的代码规范,加强团队内代码的统一性,是理所当然的;但是,认为代码可以代替文档却是不可取的,因为代码的可读性与规范的文档相比合适由一定的差距。
同时,如果没有统一的代码规范,代码全体拥有就无从谈起。
项目: 在项目实施初期,就由项目的技术经理建立代码规范,并将其作为代码审查的标准。
每周40小时工作制 ( 40-hour Week )
XP: 要求项目团队人员每周工作时间不能超过40小时,加班不得连续超过两周,否则反而会影响生产率。
评述: 该实践充分体现了XP的"以人为本"的原则。但是,如果要真正的实施下去,对于项目进度和工作量合理安排的要求就比较高。
项目: 由于项目的工期比较充裕,因此,很幸运的是我们并没有违反该实践。
计划博弈 ( Planning Game )
XP: 要求结合项目进展和技术情况,确定下一阶段要开发与发布的系统范围。
评述: 项目的计划在建立起来以后,需要根据项目的进展来进行调整,一成不变的计划是不存在。因此,项目团队需要控制风险、预见变化,从而制定有效、可行的项目计划。
项目: 在系统实现前,我们首先按照需求的优先级做了迭代周期的划分,将高风险的需求优先实现;同时,项目团队每天早晨参加一个15分钟的项目会议,确定当天以及目前迭代周期中每个成员要完成的任务。
系统隐喻 ( System Metaphor )
XP: 通过隐喻来描述系统如何运作、新的功能以何种方式加入到系统。它通常包含了一些可以参照和比较的类和设计模式。XP不需要事先进行详细的架构设计。
评述: XP在系统实现初期不需要进行详细的架构设计,而是在迭代周期中不断的细化架构。对于小型的系统或者架构设计的分析会推迟整个项目的计划的情况下,逐步细化系统架构倒是可以的;但是,对于大型系统或者是希望采用新架构的系统,就需要在项目初期进行相信的系统架构设计,并在第一个迭代周期中进行验证,同时在后续迭代周期中逐步进行细化。
项目: 开发团队在设计初期,决定参照STRUTS框架,结合项目的情况,构建了针对工作流程处理的项目框架。首先,团队决定在第一个迭代周期实现配件申请的工作流程,在实际项目开发中验证了基本的程序框架;而后,又在其它迭代周期中,对框架逐渐精化。
简单设计 ( Simple Design )
XP: 认为代码的设计应该尽可能的简单,只要满足当前功能的要求,不多也不少。
评述: 传统的软件开发过程,对于设计是自顶而下的,强调设计先行,在代码开始编写之前,要有一个完美的设计模型。它的前提是需求不变化,或者很少变化;而XP认为需求是会经常变化的,因此设计不能一蹴而就,而应该是一项持续进行的过程。
Kent Beck认为对于XP来说,简单设计应该满足以下几个原则:
1.成功执行所有的测试;
2.不包含重复的代码;
3.向所有的开发人员清晰地描述编码以及其内在关系;
4.尽可能包含最少的类与方法。
对于国内大部分的软件开发组织来说,应该首先确定一个灵活的系统架构,而后在每个迭代周期的设计阶段可以采用XP的简单设计原则,将设计进行到底。
项目: 在项目的系统架构经过验证后的迭代周期内,我们始终坚持简单设计的原则,并按照Kent Beck的四项原则来进行有效的验证。对于新的迭代周期中出现需要修改既有设计与代码的情况,首先对原有系统进行"代码重构",而后再增加新的功能。
测试驱动 ( Test-driven )
XP: 强调"测试先行"。在编码开始之前,首先将测试写好,而后再进行编码,直至所有的测试都得以通过。
评述: RUP与XP对测试都是非常的重视,只是两者对于测试在整个项目开发周期内首先出现的位置处理不同。XP是一项测试驱动的软件开发过程,它认为测试先行使得开发人员对自己的代码有足够的信心,同时也有勇气进行代码重构。测试应该实现一定的自动化,同时能够清晰的给出测试成功或者失败的结果。在这方面,xUnit测试框架做了很多的工作,因此很多实施XP的团队,都采用它们进行测试工作。
项目: 我们在项目初期就对JUNIT进行了一定的研究工作,在项目编码中,采用JBUILDER6提供的测试框架进行测试类的编写。但是,不是对所有的方法与用例都编写,而只是针对关键方法类、重要业务逻辑处理类等进行。
代码重构 ( Refactoring )
XP: 强调代码重构在其中的作用,认为开发人员应该经常进行重构,通常有两个关键点应该进行重构:对于一个功能实现和实现后。
评述: 代码重构是指在不改变系统行为的前提下,重新调整、优化系统的内部结构以减少复杂性、消除冗余、增加灵活性和提高性能。重构不是XP所特有的行为,在任何的开发过程中都可能并且应该发生。
在使用代码重构的时候要注意,不要过分的依赖重构,甚至轻视设计,否则,对于大中型的系统而言,将设计推迟或者干脆不作设计,会造成一场灾难。
项目: 我们在项目中将JREFACTORY工具部署到JBuilder中进行代码的重构,重构的时间是在各个迭代周期的前后。代码重构在项目中的作用是改善既有设计,而不是代替设计。
成对编程 ( Pair Programming )
XP: 认为在项目中采用成对编程比独自编程更加有效。成对编程是由两个开发人员在同一台电脑上共同编写解决同一问题的代码,通常一个人负责写编码,而另一个负责保证代码的正确性与可读性。
评述: 其实,成对编程是一种非正式的同级评审 ( Peer Review )。它要求成对编程的两个开发人员在性格和技能上应该相互匹配,目前在国内还不是十分适合推广。成对编程只是加强开发人员沟通与评审的一种方式,而非唯一的方式。具体的方式可以结合项目的情况进行。
项目: 我们在项目中并没有采用成对编程的实践,而是在项目实施的各个阶段,加强了走查以及同级评审的力度。需求获取、设计与分析都有多人参与,在成果提交后,交叉进行走查;而在编码阶段,开发人员之间也要在每个迭代周期后进行同时评审。
XP: 认为开发小组的每个成员都有更改代码的权利,所有的人对于全部代码负责。
评论: 代码全体拥有并不意味者开发人员可以互相推委责任,而是强调所有的人都要负责。如果一个开发人员的代码有错误,另外一个开发人员也可以进行BUG的修复。
在目前,国内的软件开发组织,可以在一定程度上实施该实践,但是同时需要注意一定要有严格的代码控制管理。
项目: 我们在项目开发初期,首先向开发团队进行"代码全体拥有"的教育,同时要求开发人员不仅要了解系统的架构、自己的代码,同时也要了解其它开发人员的工作以及代码情况。这个实践与同级评审有一定的互补作用,从而保证人员的变动不会对项目的进度造成很大的影响。
在项目执行中,有一个开发人员由于参加培训,缺席项目执行一周,由于实行了"代码全体拥有"的实践,其它的开发人员成功地分担了该成员的测试与开发任务,从而保证项目的如期交付。
持续集成 ( Continuous Integration )
XP: 提倡在一天中集成系统多次,而且随着需求的改变,要不断的进行回归测试。因为,这样可以使得团队保持一个较高的开发速度,同时避免了一次系统集成的恶梦。
评述: 持续集成也不是XP专有的最佳实践,著名的微软公司就有每日集成 ( Daily Build ) 的成功实践。但是,要注意的是,持续集成也需要良好的软件配置变更管理系统的有效支持。
项目: 使用VSS作为软件配置管理系统,坚持每天进行一次的系统集成,将已经完成的功能有效地结合起来,进行测试。
小型发布 ( Small Release )
XP: 强调在非常短的周期内以递增的方式发布新版本,从而可以很容易地估计每个迭代周期的进度,便于控制工作量和风险;同时,也可以及时处理用户的反馈。
评论: 小型发布突出体现了敏捷方法的优点。RUP强调迭代式的开发,对于系统的发布并没有作出过多的规定。用户在提交需求后,只有在部署时才能看到真正的系统,这样就不利于迅速获得用户的反馈。
如果能够保证测试先行、代码重构、持续集成等最佳实践,实现小型发布也不是一件困难的事情,在有条件的组织可以考虑使用。
项目: 项目在筹备阶段就配置了一台测试与发布服务器,在项目实施过程中,平均每两周(一个迭代周期结束后)进行一个小型发布;用户在发布后两个工作日内,向项目小组提交"用户接收测试报告",由项目经理评估测试报告,将有效的BUG提交至Rational Clear Case,并分配给相应的开发人员。项目小组应该在下一个迭代周期结束前修复所有用户提交的问题。
以上是XP的最佳实践在项目中的应用情况,让我们查看以下该项目的详细统计数据:
其中,项目执行过程中提交了一个"用户需求变更",该变更对于项目周期的影响为6个工作日。
项目实施后,在用户接收测试中,只提交了2个BUG,而且在提交当天就得到了解决。目前,项目运行平稳,并得到了用户的好评。因此,我们认为,XP在该项目中的实施有效地保证了项目质量和项目周期。
总结
RUP与XP 都是在总结了很多项目实践的过程中发展起来的软件开发过程, 只是它们在处理需求变更的方法不同。其实它们还是有很多相似之处,例如,它们的基础都是面向对象方法,都重视代码、文档的最小化和设计的简化,采用动态适应变化的演进式迭代周期等等。
目前,国内执行XP的理想情况应该是:在保持组织既有的开发过程和生命周期模型的情况下,根据应用类型、项目特点和组织文化,借鉴、采取个别对项目有效的XP做法,将RUP进行一定的剪裁,形成自己的软件开发过程。
在项目的实施过程中,我们感觉到XP对于执行者的要求是比较高的,因为它要求开发团队必须具备熟练的代码设计技能和严格的测试保障技术,了解面向对象和模式,掌握了重构和OO测试技术,习惯了测试先行的开发方式等等。
因此,对于目前国内的软件开发组织来说,应该首先加强对于软件开发过程化和系统架构设计的掌握,然后,才是利用XP等敏捷方法来完善软件开发过程。
从一个项目谈XP在国内的应用
80酷酷网 80kuku.com