为什么极限编程的实践有哪些不仅仅是一套技术实践?

XP即是一种轻量()、高效、低風险、柔性、可预测、而且充满乐趣的软件开发方式。

    (1)计划游戏计划游戏的主要思想就是先快速地制定一份概要的计划,然后随著细节的不断清晰,再逐步完善这份计划计划游戏产生的结果是一套用户故事及后续的一两次迭代的概要计划。

(2)小型发布XP 方法秉承的是持续集成、小步快走的思维,也就是说每一次发布的版本应该尽可能地小当然前提条件是每个版本有足够的商业价值,值得發布由于小型发布可以使得集成更频繁,客户获得的中间结果越频繁反馈也就越频繁,客户就能够实时地了解项目的进展情况从而提出更多的意见,以便在下一次迭代中计划进去以实现更高的客户满意度。

    (3)隐喻相对而言,隐喻比较令人费解根据词典中的解釋是:一种语言的表达手段,它用来暗示字面意义不相似的事物之间的相似之处隐喻常用于四个方面:寻求共识、发明语汇、创新嘚武器、描述。

(4)简单设计强调简单的价值观,引出了简单性假设原则落到实处就是简单设实践。这个实践看上去似乎很容噫理解但却又经常被误解,许多批评者就指责 XP 忽略设计是不正确的其实,XP 的简单设计实践并不是要忽略设计而是认为设计不应该在編码之前一次性完成,因为那样只能建立在情况不会发生变化或者我们可以预见所有的变化之类的谎言的基础上

(5)先行。对於有些而言有时候会以太紧张为理由,继而忽略测试工作这样,就导致了一个恶性循环越是没空编写测试,的效率与质量越差花在找、解决缺陷的时间也越来越多,实际产能大大降低由于产能降低,因此时间更紧张压力就更大。

    (6)重构重构是一种对代碼进行改进而不影响功能实现的,XP 需要开发人员闻到代码的坏味道时就有重构代码的勇气。重构的目的是降低变化引发的风险、使得代码更加容易

(7)结对。从 20 世纪 60 年代开始就有类似的实践在进行,长年以来的研究结果给出的结论是结对编程的效率反而比单獨编程更高。一开始虽然会牺牲一些速度但慢慢地,开发速度会逐渐加快究其原因,主要是结对编程大大降低了的成本提高了工作嘚质量。结对编程技术被誉于 XP 保证工作质量、强调人文主义的一个最典型的实践得当还能够使开发团队协作更加顺畅、知识交流与共享哽加频繁、团队稳定性也会更加牢固。

(8)集体代码所有制由于 XP 方法鼓励团队进行结对编程,而且认为结对编程的组合应该动态地搭配根据任务的不同、专业技能的不同进行最优组合。因此每一个人都会遇到不同的代码,代码的所有制就不再适合于私有因为那样会給修改工作带来巨大的不便。所谓集体代码所有制就是团队中的每个成员都拥有对代码进行改进的权利,每个人都拥有全部代码也都需要对全部代码负责。同时XP 强调代码是谁破坏的(修改后出现问题),就应该由谁来修复

    (9)持续集成。在前面谈到小型发布、重构、结对编程、集体代码所有制等最佳实践的时候多次提到持续集成,可以说持续集成是这些最佳实践的基本支撑条件

(10)每周工莋 40 小时。这是最让开发人员开心、者反对的一个最佳实践了加班、再加班早已成为开发人员的家常便饭,也是管理者最常使用的一种策畧而 XP 方法认为,加班最终会扼杀团队的积极性最终导致项目的失败,这也充分体现了 XP 方法关注人的因素比关注过程的因素更多一些鈈过,有一点是需要解释的每周工作 40 中的“40”不是一个绝对数,它所代表的意思是团队应该保证按照正常的时间” 进行工作

(11)现场客户。为了保证开发出来的结果与客户的预想接近XP 方法认为最重要的是需要将客户请到开发现场。就像计划游戏中提到过的在 XP 项目中,应该时刻保证客户负责决策开发团队负责技术决策。因此在项目中有客户在现场明确用户故事,并做出相应的业务决策对于XP 项目而言有着十分重要的意义。

(12)编码标准拥有编码标准可以避免团队在一些与开发进度无关的细枝末节问题上发生争论,而苴会给重构、结对编程带来很大的麻烦不过,XP 方法的编码标准的目的不是创建一个事无巨细的规则列表而是要能够提供一个确保代码清晰,便于交流的指导方针

Beck 认为,XP 方法的最大价值在于在项目中融会贯通地运用这 12 个最佳实践,而非单独使用当然,可以使用其中嘚一些实践但这并不意味着就应用了 XP 方法。XP 方法真正能够发挥其效能就必须完整地运用 12 个实践。

  我们希望客户、管理者和开發人员紧密地工作在一起以便于彼此知晓对方所面临的问题,并共同去解决这些问题谁是客户?XP团队中的客户是指定义产品的特性并排列这些特性优先级的人或者团体有时,客户是和开发人员同属一家公司的一组业务分析师、质量保证专家和/或者市场专家有时,客戶是用户团体委派的用户代表有时,客户事实上是支付开发费用的人但是在XP项目中,无论谁是客户他们都是能够和团队一起工作的團队成员。
  最好的情况是客户和开发人员在同一个房间中工作次一点的情况是客户和开发人员之间的工作距离在100m以内。距离越大愙户就越难成为真正的团队成员。如果客户工作在另外一幢建筑或另外一个州那么他将会很难融合到团队中来。
  如果确实无法和客戶工作在一起该怎么办呢?我的建议是去寻找能够在一起工作、愿意并能够代替真正客户的人


  为了进行项目计划,必须要了解需求但是却无需了解得太多。对于做计划而言了解需求只需要到能够估算它的程度就足够了。你可能认为为了对需求进行估算,就必須要了解该需求的所有细节其实并非如此。你必须知道存在很多的细节也必须知道细节的大致分类,但是你不必知道特定的细节
  需求的具体细节很可能会随时间而改变,一旦客户开始看到集成到一起的系统就更会如此。看到新系统的问世是关注需求的最好时刻因此,不要去捕获某个在很长一段时间之后才会实现的需求的特定细节否则很可能会导致无用功以及对需求不成熟的关注。
  在XP中我们和客户反复讨论,以获取对于需求细节的理解但是不去记录那些细节。我们更愿意客户在索引卡片上写下一些共识的言语这些呮言片语可以提醒我们记起这次交谈。基本上在客户进行书写的同一时刻开发人员在该卡片上写下对应于卡片上需求的估算。估算是基於在和客户进行交谈期间所得到的对于细节的理解进行的
  用户故事(user story)就是正在进行的关于需求的谈话的助记符。它是一个计划工具客户可以使用它并根据需求的优先级和估算代价来安排实现该需求的时间。
  XP项目每两周交付一次可以工作的软件每两周的迭代嘟实现了利益相关者的一些需求。在每次迭代结束时会给利益相关者演示迭代生成的系统,以得到他们的反馈
  每次迭代通常耗时兩周。迭代是一次较小的交付可能会被加入到产品中,也可能不会迭代计划由一组用户故事组成,这些用户故事是客户根据开发人员確定的预算选出来的
  开发人员通过度量在以前的迭代中所完成的工作量来为本次迭代设定预算。只要估算成本的总量不超过预算愙户就可以为本次迭代选择任意数量的用户故事。
  一旦迭代开始客户就同意不再修改当次迭代中用户故事的定义和优先级别。迭代期间开发人员可以自由地将用户故事分解成任务(task),并依据最具技术和商业意义的顺序来开发这些任务
  XP团队通常会创建一个发咘计划来规划出随后大约6次迭代的内容。这就是所谓的发布计划一次发布通常需要3个月的工作。它表示了一次较大的交付通常此次交付会被加入到产品中。发布计划是由客户根据开发人员给出的预算所选择的、排好优先级别的一组用户故事组成
  开发人员通过度量茬以前的发布中所完成的工作量来为本次发布设定预算。只要估算成本的总量不超过预算客户就可以为本次发布选择任意数目的用户故倳。客户同样可以决定在本次发布中用户故事的实现顺序如果开发团队强烈要求的话,客户可以通过指明哪些用户故事应该在哪次迭代Φ完成的方式制订出发布中最初几次迭代的内容。
  发布计划不是一成不变的客户可以随时改变发布的内容。他可以取消用户故事编写新的用户故事,或者改变用户故事的优先级别但是,客户应该尽量不去更改一次迭代
  可以以客户指定的验收测试的形式来記录有关用户故事的细节。用户故事的验收测试是在就要实现该用户故事之前或者在实现该用户故事的同时才开始编写的。验收测试使鼡脚本语言编写这样它们可以自动、反复地运行。这些测试共同来验证系统是否按照客户指定的行为运转
  验收测试是由业务分析師、质量保证专家以及测试人员在迭代期间编写的。编写验收测试使用的语言对于程序员、客户以及业务人员来说都很容易阅读和理解程序员就是从这些测试中了解他们正在实现的故事的真实工作细节。这些测试成为真正的项目需求文档验收测试描述了每个特性的所有細节,并用作验证这些特性是否被正确完成的决定性依据
  一旦通过一项验收测试,就将该测试加入到已经通过的验收测试集合中並决不允许该测试再次失败。这个不断增长的验收测试集合每天会多次运行每当系统被创建时,都要运行这个验收测试集如果一项验收测试失败了,那么系统创建就宣告失败因而,一项需求一旦被实现就再不会遭到破坏。系统从一种工作状态迁移到另一种工作状态期间,系统的不能工作状态时间决不允许超过几个小时
  代码都是由结对的程序员使用同一台工作站共同完成的。结对人员中一個控制键盘并输入代码。另一个观察着输入的代码寻找着代码中的错误和可以改进的地方。两个人认真地进行着交互他们都全身心地投入到软件的编写中。
  两人频繁互换角色控制键盘的可能累了或者遇到了困难,他的同伴会取得键盘的控制权在一个小时内,键盤可能在他们之间来回传递好几次最终生成的代码是由他们两人共同设计、共同编写的,两人功劳均等
  结对的关系要经常变换。烸天至少要改变一次这样每个程序员在一天中可以在两个不同的结对中工作。在一次迭代期间每个团队成员应该和所有其他的团队成員在一起工作过,并且他们应该参与了本次迭代中所涉及的每项工作
  结对编程会极大地促进知识在团队中的传播。仍然会需要一些專业知识那些需要一定专业知识的任务通常需要合适的专家去完成,但是那些专家几乎将会和团队中的所有其他人结对这将加快专业知识在团队中的传播。这样在紧要关头,其他团队成员就能够代替所需要的专家Williams 和Nosek 的研究表明,结对非但不会降低编程人员的效率反而会大大减少缺陷率。
  第4章会详细地讨论这个主题在此,我们仅进行大致的介绍
  编写所有产品代码的目的都是为了使失败嘚单元测试能够通过。首先编写一个单元测试由于它要测试的功能还不存在,所以它会运行失败然后,编写代码使测试通过
  编寫测试用例和代码之间的更迭速度是很快的,基本上在几分钟左右测试用例和代码共同演化,其中测试用例循序渐进地对代码的编写进荇指导(参见第6章中的例子)
  作为结果,一个非常完整的测试用例集就和代码一起发展起来程序员可以使用这些测试来检查程序昰否正确地工作。如果结对的程序员对代码进行了小的更改那么他们可以运行测试,以确保更改没有对程序造成任何的破坏这会非常囿利于重构(在本章后面介绍)。
  当为了使测试用例通过而编写代码时那么所编写的代码天生就是可测试的。更重要的是这样做會强烈地激发你去解除各个模块间的耦合,以便能够独立地对它们进行测试因而,以这种方式编写的代码的设计往往具有更弱的耦合媔向对象设计的原则在进行这种解耦方面具有巨大的帮助作用(参见本书第二部分)。
  每一对编程者都具有签出(check out)任何模块并对它進行改进的权力每个程序员都不会对任何一个特定的模块或技术单独负责。每个人都参与GUI方面的工作每个人都参与中间件方面的工作,每个人都参与数据库方面的工作任何人都不会比其他人在一个模块或者技术上具有更多的权威。
  这并不意味着XP不需要专业知识洳果你的专业领域是有关GUI的,那么你最有可能去从事GUI方面的任务但是你也将会被邀请去和别人结对从事有关中间件和数据库方面的任务。如果你决定去学习另一门专业知识那么你可以承担相关的任务,并和能够传授你这方面知识的专家一起工作你不会被限制在自己的專业领域。
  程序员每天会多次签入(check in)他们的代码并进行集成规则很简单:第一个签入的只要完成签入就可以了,所有后面签入的囚负责代码的合并工作
  XP团队使用非阻塞的源代码控制工具。这就意味着程序员可以在任何时候签出任何模块而不管是否有其他人巳经签出了这个模块。当程序员完成了对于模块的修改并把该模块签入时他必须把他所做的改动和在他前面签入该模块的程序员所作的任何改动进行合并。为了避免合并的时间过长团队的成员会非常频繁地检查他们的模块。
  结对人员会在一项任务上工作一到两个小時他们创建测试用例和产品代码。在某个适当的间歇点也许远在这项任务完成之前,他们决定把代码签入回去他们首先确保所有的測试都能够通过,然后把新的代码集成进当前的代码库中如果需要,他们会对代码进行合并如果有必要,他们会和在签入上有冲突的其他程序员协商一旦集成进了他们的更改,他们就构建新的系统他们运行系统中的每一个测试,包括当前所有有效的验收测试如果怹们破坏了原先可以工作的部分,他们会进行修正一旦所有的测试都通过了,他们就算完成了此次签入工作
  因而,XP团队每天会进荇多次系统构建他们会从头开始创建整个系统。如果系统的最终结果是一张CD他们就刻录该CD。如果系统的最终结果是一个可以访问的Web站點他们就安装该Web站点,或许会把它安装在一个测试服务器上

2.1.9 可持续的开发速度


  软件项目不是全速短跑,它是马拉松长跑那些一躍过起跑线就开始尽力狂奔的团队将会在远离终点前就筋疲力尽。为了快速地完成开发团队必须要以一种可持续的速度前进。团队必须保持旺盛的精力和敏锐的警觉团队必须要有意识地保持稳定、适中的速度。
  XP的规则不允许团队加班工作在版本发布前的一个星期昰该规则的唯一例外。如果发布目标就在眼前并且能够一蹴而就则允许加班。
  团队在一个开放的房间中一起工作房间中有一些桌孓。每张桌子上摆放了两到三台工作站每台工作站前有两把椅子。墙壁上挂满了状态图表、任务明细表、UML图等等。
  房间里充满了茭谈的嗡嗡声结对编程的两人坐在互相能够听得到的距离内,每个人都可以得知另一人是否遇到了麻烦每个人都了解对方的工作状态,程序员们都处在适合于激烈地进行讨论的位置上
  可能有人认为这种环境会分散人的注意力。很容易会让人担心由于持续的噪音和幹扰而一事无成事实上并非如此。而且密歇根大学的一项研究表明,在“充满积极讨论的屋子”(war room)里工作生产率非但不会降低,反而会成倍地提高
  第3章中会详细介绍XP的计划游戏。在这里仅做简要介绍。
  计划游戏(planning game)的本质是划分业务和开发之间的职责业务人员(也就是客户)决定特性的重要性,开发人员决定实现一个特性所花费的代价
  在每次发布和迭代的开始,开发人员向客戶提供一个预算客户选择那些所需的代价合计起来小于等于该预算的用户故事。开发者所提供的预算是基于他们在最近一次迭代或者发咘中所完成的工作量进行的
  依据这些简单的规则,采用短周期迭代和频繁的发布很快客户和开发人员就会适应项目的开发节奏。愙户会了解开发人员的开发速度基于这种了解,客户能够确定项目会持续多长时间以及会花费多少成本。
  XP团队使他们的设计尽可能的简单、有表达力此外,他们仅仅关注于计划在本次迭代中要完成的用户故事而不会考虑那些未来的用户故事。团队更愿意在一次佽的迭代中不断地变迁系统的设计使之对正在实现的用户故事而言始终保持在最优状态。
  这意味着XP团队的工作可能不会从基础设施開始他们并不先去选择数据库或者中间件,而是先以最简单的可能方式实现第一批用户故事只有当出现一个用户故事迫切需要基础设施时,他们才会引入该基础设施
  下面3条XP指导原则(mantra)可以对开发人员进行指导。
  (1) 考虑能够工作的最简单的事情XP团队总是尽可能寻找能实现当前用户故事的最简单的设计。在实现当前的用户故事时如果能够使用平面文件,就不去使用数据库;如果能够使用简单嘚socket连接就不去使用ORB或者Web Service;如果能够不使用多线程,就别去用它我们尽量考虑用最简单的方法来实现当前的用户故事。然后选择一种峩们能够实际得到的和该简单性最接近的解决方案。
  (2) 你不需要它是的,但是我们知道总有一天会需要数据库会需要ORB,也总有一天嘚去支持多用户所以,我们现在就需要为那些东西做好准备不是吗?
  如果在确实需要基础设施前拒绝引入它那么会发生什么呢?XP团队会对此进行认真的考虑他们开始时假设将不需要那些基础设施。只有在有证据或者至少有十分明显的迹像表明现在引入这些基礎设施比继续等待更加合算时,团队才会引入这些基础设施
  (3) 一次,并且只有一次极限编程的实践有哪些者不能容忍重复的代码。無论在哪里发现重复的代码他们都会消除这些重复。
  导致代码重复的因素有许多最明显的是通过鼠标选中一段代码,然后四处进荇粘贴当发现那些重复的代码时,我们会通过创建一个函数或基类的方法来消除它们有时两个或多个算法非常相似,但是它们之间又存在有微妙的差别我们会把它们变成函数,或者使用TEMPLATE METHOD模式(请参见第22章)无论重复代码源于何处,一旦发现就必须被消除。
  消除重复最好的方法就是抽象毕竟,如果两种事物相似的话必定存在某种抽象能够统一它们。这样消除重复的行为会迫使团队提炼出許多的抽象,并进一步减少代码间的耦合
  第5章会对重构进行详细的讨论 ,下面只是一个简单的介绍
  代码往往会腐化。随着我們添加一个又一个的特性处理一个又一个的错误,代码的结构会逐渐退化如果对此置之不理的话,这种退化最终会导致纠结不清、难於维护的混乱代码
  XP团队通过经常性的代码重构来扭转这种退化。重构就是在不改变代码行为的前提下对其进行一系列小的改造,旨在改进系统结构的实践活动每个改造都是微不足道的,几乎不值得去做但是所有的这些改造叠加在一起,就形成了对系统设计和构架显著的改进
  在每次细微改造之后,我们都会运行单元测试以确保改造没有造成任何破坏然后再去做下一次改造。如此往复周洏复始。通过这种方式我们可以在改造系统设计的同时,保持系统可以工作
  重构是持续进行的,而不是在项目结束时、发布版本時、迭代结束时甚至每天快下班时才进行的重构是我们每隔一个小时或者半个小时就要去做的事情。通过重构我们可以持续地保持代碼尽可能干净、简单并且具有表达力。
  隐喻(metaphor)是唯一一个不具体、不直接的XP实践也是所有XP实践中最难理解的一个。极限编程的实踐有哪些者在本质上都是务实主义者隐喻这个缺乏具体定义的概念使我们觉得很不舒服。的确一些XP的支持者经常讨论把隐喻从XP的实践Φ去除。然而在某种意义上,隐喻却是XP所有实践中最重要的实践之一
  想象一下智力拼图玩具。你怎样知道如何把各个小块拼在一起显然,每一块都与其他块相邻并且它的形状必须与相邻的块完美地吻合。如果你眼睛看不见但是具有很好的触觉那么通过锲而不舍地筛选每个小块,不断地尝试它们的位置也能够拼出整个图形。
  但是相对于各个小块的形状而言,还有一种更为强大的力量把這些复杂的小块拼装在一起这就是整张拼图的图案。图案是真正的向导它的力量是如此之大,以至于如果图案中相邻的两块不具有互楿吻合的形状那么你就可以断定拼图玩具的制作者把玩具做错了。
  这就是隐喻它是将整个系统联系在一起的全局视图。它是系统嘚愿景是它使得所有单独模块的位置和外观变得明显直观。如果模块的外观与整个系统的隐喻不符那么你就知道该模块是错误的。
  隐喻通常可以归结为一个名字系统这些名字提供了一个系统组成元素的词汇表,并且有助于定义它们之间关系
  例如,我曾经开發过一个以每秒60个字符的速度将文本输出到屏幕的系统以这样的速度,字符充满整个屏幕需要一段时间所以我们让产生文本的程序把產生的文本放到一个缓冲区中。当缓冲区满了的时候我们把该程序交换到磁盘上。当缓冲区快要变空时我们把该程序交换回来并让它繼续运行。
  我们用装卸卡车拖运垃圾来比喻整个系统缓冲区是小卡车。屏幕是垃圾场程序是垃圾制造者。所有的名字相互吻合這有助于我们从整体上去考虑系统。
  举另一个例子我曾经开发过一个分析网络流量的系统。每30分钟系统会轮询几十个网络适配器,并从中获取监控数据每个网络适配器为我们提供一小块由几个单独变量组成的数据。我们称这些数据块为“面包切片”这些面包切爿是待分析的原始数据。分析程序“烤制”这些切片因而被称为“烤面包机”。我们把数据块中的单个变量称为“面包屑”总之,它昰一个有用并且有趣的隐喻
  当然,隐喻不仅仅是一个名字系统隐喻是系统的愿景,它指导着所有开发者去选择合适的名字把函數放到合适的位置,创建出新的合适的类和方法等等。
  极限编程的实践有哪些是一组简单、具体的实践这些实践结合在一起形成叻一个敏捷开发过程。极限编程的实践有哪些是一种优良、通用的软件开发方法对于大多数项目团队来说,可以拿来直接采用也可以增加一些实践,或者对其中的一些实践进行修改后再采用

       摘自:敏捷软件开发:原则、模式与实践(C#版)

我要回帖

更多关于 极限编程的实践有哪些 的文章

 

随机推荐