UML软件工程组织

Extreme Programming (XP)实践

v 1.0 
整理: XPChina BrokenDoor 
(摘自文章集锦)

1 为什么是XP

让我们来考虑一个传统的途径:用户组和开发组协商让一个分析员设计一个项目。在几周和几个月中,分析员和用户每天会面几个小时。分析员生产出一套文档,可能还包括象一个可视描述和用例之类。用户和项目经理(也可能是编程团队)回顾这些文档并且协商出一个发行版。程序员使用规范在几个月之后成长出一个系统,或多或少的实现了原来的想法。在结束的时候这通常是一个闭呼叫系统,当人们发现他们所遗漏的并意识到自从文档被写好以来什么都已经改变了。最后,用户加入进来作一个用户接受测试然后系统被发布。 

通常整个过程所花费的时间比任何人所期望的都长,会遗漏一些特征,并且质量并不是用户想要的。更有甚着,文档也不再随日期更新。 

问题总结: 
不能完全理解用户需求(用户自己也经常不清楚自己需要什么) 
用户的要求不断变化 
技术更新速度很快 
开发人员缺乏成功经验 
开发小组不稳定 
没有完整的测试设计 


--------------------------------------------------------------------------------


2 XP简介

XP全名Extreme Programming ,一种轻量级,灵活的方法。 
XP 规定了一组核心价值和方法,可以让软件开发人员发挥他们的专长:编写代码。XP 消除了大多数重量型过程的不必要产物,通过减慢开发速度、耗费开发人员的精力(例如干特图、状态报告,以及多卷需求文档)从目标偏离。 
在XP中,在用户vs程序员的角色中有一个基本的分隔。用户拥有*what you get*,而程序员拥有*what it costs*。这显示了谁能作出什么决定。 即用户做企业决策,程序员做技术决策。 

2.1 用户决定: 

范围:什么系统是必须作的。 

优先级:对于企业价值什么是最重要的。 

发行的组合:什么是必须在发行版中的,一定是有用的? 

发行的日期:什么时候需要发行? 

2.2 程序员决定: 

评估添加一个特征的时间 ,以及每个特征的风险 

使用各种技术选项所花费的成本 :程序员解释程序选择的结果,但是用户作决定 

过程:小组怎么样工作,团队怎么组织 

细节时间表:在一个迭代中特征先开发风险最大的那一个特征可以减轻风险 

2.3 XP 的核心价值为: 

交流。 项目的问题往往可以追溯到某人在某个时刻没有和其他人一起商量某些重要问题上。使用 XP,不交流是不可能的事。 


简单。 XP 建议您总是尽可能围绕过程和编写代码做最简单的事情。按照 Beck 的说法,“XP 就是打赌。它打赌今天最好做些简单的事...而不是做更复杂但可能永远也不会用到的事。” 


反馈。 更早和经常来自客户、团队和实际最终用户的具体反馈意见为您提供更多的机会来调整您的力量。反馈可以让您把握住正确的方向,少走弯路。 


勇气。 勇气存在于其它三个价值的环境中。它们相互支持。需要勇气来相信一路上具体反馈比预先知道每样事物来得更好。需要勇气来在可能暴露您的无知时与团队中其他人交流。需要勇气来使系统尽可能简单,将明天的决定推到明天做。而如果没有简单的系统、没有不断的交流来扩展知识、没有掌握方向所依赖的反馈,勇气也就失去了依靠。 


--------------------------------------------------------------------------------


3 XP的十二种实践方法: 


重新划分(Refactoring) 

系统比喻(Metaphor) 

简单设计(Simple design) 

一周40小时 (40-hour week) 

编码标准(Coding standards) 

持续集成(Continuous integration) 

成对编程(pair programming) 

集体代码所有权(Collective ownership) 

现场客户(On-site customer) 

规划策略(Planning game) 

小发行版(Small releases) 

测试(Testing) 

3.1 规划策略 
有些人会指责 XP 是一种美其名的剽窃,只是一群牛仔在没有任何规则的情况下将一个系统拼凑在一起。错。XP 是为数不多的几种承认您在开始时不可能事事通晓的方法之一。无论是用户还是开发人员都是随着项目的进展过程才逐步了解事物的。只有鼓励和信奉这种更改的方法才是有效方法。状态限定方法忽视更改。而 XP 则留心更改。它倾听所用的方法就是*规划策略*,一个由 Kent Beck 创造的概念。 
这一方法背后的主要思想是迅速地制定粗略计划,然后随着事物的不断清晰来逐步完善。规划策略的产物包括:一堆索引卡,每一张都包含一个客户素材,这些素材驱动项目的迭代;以及对下一两个发行版的粗略计划,如 Kent Beck 和 Martin Fowler 在他们的 Planning Extreme Programming 中描述的那样。让这种形式的计划得以发挥作用的关键因素是让用户做企业决策,让开发小组做技术决策。如果没有这一前提,整个过程就会土崩瓦解。 

3.2 系统比喻 
体系结构是做什么用的?它提供了系统各种组件以及它们是如何交互的画面 -- 一种映射,可以让开发人员了解新的代码部分适合放在哪里。 
XP 中的系统比喻与大多数方法称作的体系结构差不多。比喻为团队提供了一致的画面,他们可以用它来描述现有系统的工作方式、新部件适合的位置,以及它们应该采取的形式。 
重要的是要记住,关键要让每个人理解系统是如何组合在一起的,而不是美丽的比喻。有时您就是无法想到一个好的比喻。想到时就太好了。  

3.3 测试 
在 XP 中有两种测试: 
1. 单元测试 
2. 验收测试 
开发人员在他们编写代码的同时编写单元测试。客户在他们定义了素材后编写验收测试。单元测试及时告诉开发人员系统在某一点上是否*工作*。验收测试告诉团队系统是否执行用户希望它执行的操作。 
假设团队使用的是如 Java 这样的面向对象语言,开发人员在为一些方法编写代码之前为每种有可能失败的方法编写单元测试。然后他们编写足够的代码使之能通过测试。有时人们会发现这有点奇怪。答案很简单。编写测试首先为您提供: 

一组可能最完整的测试 

可能能工作的最简单的代码 

代码意图的明确景象 
开发人员只有在通过所有单元测试后才可以将代码检入到源代码资源库中。单元测试使开发人员有信心相信他们的代码能够工作。这为其他开发人员留下线索,可以帮助他们理解最早的开发人员的意图(实际上,这是我们看到过的最好的文档)。单元测试还给了开发人员勇气重新划分代码,因为测试失败可以立刻告诉开发人员存在错误。应该将单元测试自动化,并提供明确的通过/失败结果。xUnit 框架做到的远不止这些,因此大多数 XP 小组都使用它们。 
用户负责确保每个素材都有验收测试来确认它们。用户可以自己编写测试、可以征募组织中的其他成员(例如 QA 人员或业务分析员)编写它们,也可以将这两种方法结合起来。测试告诉他们系统是否具有应该具有的那些特性,以及是否可以正确工作。理想情况下,用户在迭代完成之前就应该写好迭代中那些素材的验收测试了。应该将验收测试自动化,并要经常运行来确保开发人员在实现新特性时没有破坏任何现有的特性。通常情况下,客户需要来自开发团队的某些帮助来编写验收测试。我们对一个项目开发一个可重用的自动验收测试框架,可以让用户在简单编辑器中输入他们的输入和所期望的输出。框架将输入转换成 XML 文件、运行文件中的测试,然后为每个测试显示*通过*或*失败*。客户喜欢这一做法。 
不是所有验收测试都必须在所有情况下通过。问题是验收测试帮助客户衡量项目*完成*的情况如何。它们还可以让客户获悉有关某些事物是否可以发行的决定。 

3.4 重构 
重构是在不更改功能性的前提下对代码加以改进。XP 小组在进行重构时毫不手软。 
开发人员重构有两个重要时机:实现特性之前和之后。开发人员尝试确定更改现有代码是否可以让新特性的开发更容易。他们查看刚刚写好的代码,看是否有方法可以对它进行简化。例如,如果他们认为有抽象的机会,就会进行重构来从具体实现中除去重复的代码。 
XP 建议您应该编写可能运行的最简单的代码,但同时也建议您应该不断学习。重构让您将学到的知识加入到代码中,同时又不会破坏测试。它使您的代码简练。这意味着它可以存在相当长的时间、为以后的开发人员引入更少问题,并为他们指引正确的方向。 

3.5 成对编程 
使用 XP,成对的开发人员编写所有产品代码。这种方式听上去好象缺乏效率。Martin Fowler 说,*当人们说成对编程降低生产力时,我回答,'那是因为大多数耗费时间的编程部分是靠输入来完成的。'*实际上,成对编程无论在经济还是其它方面都提供了许多好处: 

所有设计决策都牵涉到至少两个人。 

至少有两个人熟悉系统的每一部分。 

几乎不可能出现两个人同时疏忽测试或其它任务。 

改变各对的组合在可以在团队范围内传播知识。 

代码总是由至少一人复查。 
研究还显示成对的编程实际上比单独编程更有效。 

3.6 小发行版 
发行版应该尽可能地小,同时仍然提供足够的企业价值以证明它们值得。 
只要觉得有意义就可以发布系统。这样就尽可能早为用户提供了价值(请记住,今天的钱比明天的钱来得值钱)。小发行版将为开发人员提供具体的反馈意见,告诉他们哪些符合客户需要,哪些不符合客户需要。然后,小组可以将这些经验教训包括在其下一发行版的规划中。 

3.7 简单的设计 
XP 的诽谤者说该过程忽略了设计。事实不是这样。问题是重量型方法建议您做的不过是提前完成大部分琐碎的设计任务。这就象是拍一张静态的地平线的照片,静止不动,然后尝试画一张如何到达那里的完美的地图。XP 说设计不应该在事物将保持不变的前提下预先仓促进行。XP 认为设计非常重要,因此应该是一个持续的事务。我们总是先尝试使用能够工作的最简单的设计,然后随着现实的不断显现来更改它。 
什么是可能工作的最简单的设计?它是符合以下条件的设计: 

运行所有测试 

不包含重复代码 

明确陈述程序员对所有代码的意图 

包含尽可能最少的类和方法 
对简单设计的需求并不是说所有设计都很小,也不表示它们是无足轻重的。它们只不过需要尽可能简单,但是仍能工作。不要包括不使用的额外特性。我们称这样的事物为 YAGNI,表示*您将不需要它(You Aren't Going to Need It)。*不要让 YAGNI 破坏您成功的机会。 

3.8 集体代码所有权 
小组中的任何人都应该有权对代码进行更改来改进它。每个人都拥有全部代码,这意味着每个人都对它负责。这种技术可以让人们对部分代码进行必要的更改而不用经过代码拥有者个人的瓶颈。每个人都负责这一事实消除了无代码所有权所带来的混乱。 

每人拥有所有代码*与*没人拥有代码*的说法并不一样。没人拥有代码时,人们可以随处进行破坏而不必负任何责任。而 XP 说,*如果是您破坏的,应该您来弥补。*我们有一些必须在每次集成之前和之后运行的单元测试。如果您破坏了某些事物,您要负责进行修补,无论它位于代码的哪一部分。这需要极端规则。可能这是名称中带有*极端*的另一个原因。 

3.9 持续的集成 
经常进行代码集成可以帮助您避免集成梦魇。XP 团队在一天中集成了代码几次,每次都在所有单元测试对系统运行后执行。 
传统方法工作方式如下:编写大量代码后执行一次大爆炸式的集成,然后花费相当长的时间来改正问题。这种笨拙的形式的确使项目速度减缓。大爆炸式的集成给团队立即带来大量问题,并且这些问题通常都有几百种可能的原因。 
如果经常进行集成,任何特定集成失败的原因都会非常明显(以前运行过测试,因此错误一定是新事物犯下的)。使用这种方法,当遇到问题时,可能的原因就相当有限。修改起来更容易,花的时间少得多,使团队保持最快速度前进。 

3.10 现场客户 
要使功能最理想,XP 小组需要在现场有一位客户来明确素材,并做出重要的企业决策。开发人员是不允许单独做这些事情的。让客户随时在场可以消除开发人员等待决策时出现的瓶颈。 
XP 不会假装素材卡是开发人员交付必要代码所需的唯一指示。素材是对以后在客户和开发人员之间填写细节的对话的一项承诺。与将所有要求写在一个静态文档中不同,其思想是进行面对面的交流,减少产生误解的机会。 
我们发现让客户在现场是可能最好的一种情形,但这不是解决问题的唯一方案。底线是客户必须随时在需要回答问题和根据企业价值为团队提供指示时有空。如果客户并非在现场专职陪伴团队的情况下就能做到这些,那很好。如果能和团队待在一起,这会更方便,但只是建议而已。 

3.11 编码标准 
拥有编码标准有两个目的: 

防止团队被一些例如事物没有以最大速度发展这种无关紧要的愚蠢争论搞得不知所措。 

它支持其它方法。 
如果没有编码标准,重新划分代码会更加困难,按应当的频度交换对更困难,快速前进也更困难。目标应该是团队中没有人辨认得出是谁写的哪一部分代码。以团队为单位对某一标准达成协议,然后遵守这一标准。目标不是创建一个事无巨细的规则列表,而是提供将确保您的代码可以清晰交流的指导方针。编码标准开始时应该很简单,然后根据团队经验逐步进化。不要预先花费太多时间。创建能够工作的最简单标准,然后逐步发展。 

3.12 一周 40 小时 
Kent Beck 说他希望*...每天早晨都感到有活力有激情,每天晚上都感到疲惫而满足。*一周 40 小时工作可以让您做到这一点。确切的小时数并不重要,重要的是原则。长时间地持续工作会扼杀工作绩效。疲劳的开发人员会犯更多错误,从长期来说,将比按*正常*时间表进行的开发慢得多。 
即使开发人员可以在长时间很好工作,这也不意味着他们应该这样。最终他们会厌倦,会离开他们的工作,或者产生影响他们工作绩效的非工作问题。如果您打乱了人们的生活,将会尝到它所带来的恶果。加班并不是解决项目问题的答案。实际上,它是更大问题的症状。如果您要走向灭亡,就无药可救了。 


--------------------------------------------------------------------------------


4 XP过程中的各个阶段

作为一个软件开发过程,XP中计划,设计,编码和测试各阶段包括的内容比较简洁,容易实施。 

4.1 计划 

User stories的编写 

识别需求方面 

开发计划的制定 

经常构造版本 

版本控制 

Load Factor因子的确定 

将项目分解为各个迭代期 

每个迭代期开始时制定计划 

人员集中 

站着开每日晨会 

当实施遇到困难时及时修正 

4.2 测试 

所有代码均需进行单元测试 

发行之前所有代码必须通过单元测试 

Bug发现后应马上测试   

4.3 编码 

始终获得用户的支持 

代码的书写必须按照规范 

所有代码均采用配对开发 

一次只能有一对开发人员进行发行 

代码经常集成 

代码共享 

将优化放在最后 

不要加班 

4.4 设计 

简单化 

采用编程规范 

设计时使用CRC卡片 

使用Spike Solution 方法 

不要过早添加新功能 

尽可能保持程序的简洁性 


 


版权所有:UML软件工程组织