前言

本文翻译自 Agile Alliance 的 Extreme Programming 词条,仅为学习之用,如有版权方面问题,请与我联系。原文档请点击Extreme Programming


定义

极限编程是一种软件开发框架,旨在生产出高质量的软件同时保证开发团队有高质量的生活状态。极限编程是最明确具体的敏捷框架,关注于适当的软件开发工程实践。

何时适用极限编程

关于极限编程的总体适用情况的特点,在 Don Wells 的网站中已经有过描述www.extremeprogramming.org

  • 动态变化的软件需求
  • 在有日期要求的项目中使用新技术而造成的风险
  • 在同一地点工作的小而精的开发团队
  • 使用自动化单元和功能测试的技术

由于全套极限编程工程实践在某些方面具有特殊性,因此在有些时候你可能不想使用全部实践。在博文When is XP Not Appropriate on the C2 Wiki中,举了一些关于何时不适用极限编程的很好的例子。

虽然在许多场景中不适用全套的极限编程实践,但这并不妨碍在给定的环境中使用尽可能多的实践。

价值取向

极限编程的五大价值取向是沟通、简化、反馈、勇气和尊重。下面将进行详细描述。

沟通

软件开发本质更像一种团队体育运动,依靠沟通将知识从某个团队成员传递到其他团队成员。极限编程强调适当形式的沟通——即在白板和其它绘图工具的帮助下进行面对面的讨论。

简化

简化的意思是“最简单的可行方法是什么?”。这样做的目的是避免资源浪费,只做那些绝对必要的工作,例如采用尽可能简单的系统设计以便进行运行、维护和支持。简化同时意味着只完成已知的需求,不要去预测未来。

反馈

通过对之前工作持续地反馈,团队可以认识到可优化的方面并且修正实践。反馈同样支持简单设计。你的团队构建了产品,然后收集关于设计和实现的反馈,最后推动产品的进步。

勇气

Kent Beck 定义勇气为“面对恐惧时的有效行为”。此定义显示了基于其他原则的行动偏好,因此结果不会对团队造成危害。你需要勇气去提出组织管理上的问题,尽管这可能降低团队效率。你需要勇气去停止手头上的无效工作并且尝试其它方式。你需要勇气去接受并应对反馈,尽管有时它很难接受。

尊重

团队成员需要互相尊重,以便于沟通、提供和接受反馈,并且在共同工作的过程中发现简单设计和解决方案。

实践

极限编程的核心就是如下所示的一组互相联系的软件开发实践。尽管这些实践可以独立实行,许多团队已经发现,有些实践之间可以互相增强,应该共同实行以便彻底消灭在软件开发中的风险。

极限编程在初次被提出之后又做出了一些改变。如果你想知道这些实践在最初是被如何描述的,请看 http://ronjeffries.com/xprog/what-is-extreme-programming

  • The Planning Game 计划会议
  • Small Releases 小型发布
  • Metaphor 系统隐喻
  • Simple Design 简单设计
  • Testing 测试
  • Refactoring 重构
  • Pair Programming 结对编程
  • Collective Ownership 集体所有
  • Continuous Integration 持续集成
  • 40-Hours Week 每周 40 小时工作
  • On-site customer 客户现场
  • Coding Standard 编码规范

正如在《极限编程——拥抱变化》第二版中的提到的,下面是对这些实践的解释。这些描述包括基于许多实践极限编程并反映出更实际的实践经验的改进。

坐一起

由于沟通是极限编程五大价值取向之一,人们又大多认为面对面交流是最有效的形式,所以让你的团队在一个没有隔挡的空间中工作吧。

团队合作

负责某个产品的有必要角色的跨职能人员小组组成一个团队。这意味着有需求的人以及在满足需求中发挥一定作用的所有人每天都共同努力以实现特定的结果。

易于交流的工作环境

将团队的工作环境设计得易于面对面沟通,当然也要允许一些必要的个人空间。使团队的工作对彼此以及团队外部的相关方透明。利用一些信息共享工具来传播信息。

专注工作

当在做软件开发或者其它脑力工作时,当你可以专心不为外界打扰时,效率是最高的。专注工作意味着你从身体和精神都处于集中状态。这意味着不要过度工作,也不要其它人给你过多压力。保持健康,同时也尊重你的组员以保证他们的健康。

结对编程

结对编程的意思是所有产品代码都由两个坐在一起共享开发机器人来完成。这个实践背后的思想就是两个人的头脑总比一个人的要强。你可以随时进行 code review 并且获得关于可能拖累你进度的疑难问题的反馈。

使用结对编程的团队发现这种操作可以提高代码质量并且不会花费两倍的成本,原因是他们可以更快地解决问题并专注于手头的工作,他们可以用更少的代码去完成同样的工作。

用户故事

描述了产品应该完成哪些对用户有意义的功能。这些故事旨在简短描述用户希望能够使用该产品做的事情,同时可用于开发计划并在团队着手实现该特定故事时提醒进行更详细的讨论。

周循环

周循环是迭代的同义词。在极限编程中,团队成员在每周第一天开会讨论每日工作计划,客户来选择他们所希望这周完成的用户故事,团队来决定如何完成。这周末的目标就是测试完毕并运行这些被选中的用户故事。

这个定时交付周期背后的思路就是给客户完成功能并得到反馈。

季度循环

季度循环是发布版本的同义词。该目的是保证在整个项目的背景下,保证每周循环的工作细节。客户就季度内需要的功能给团队制定一个宏观计划,避免团队陷入细节。它还可以帮助客户与其他利益相关者合作,这些利益相关者可能就一些功能何时可用有想法。

谨记在制定一个季度计划的时候,任何一个特定的用户故事都处在一个更高的级别。用户故事交付的顺序和内容在季度计划中都可能发生改变。如果你检查每周做计划回顾的话,可以保证团队成员都知晓变化情况以最小化变化带来的意外状况。

松弛

松弛背后的思想是在每周或季度工作计划中加入一些低优先级或不重要的任务,当团队进度落后的时候可以舍弃掉这些用户故事。换句话说,要考虑预估时间的内在变化性,以确保您有很大的机会实现自己的预期。

十分钟构建

十分钟构建的目标是在 10 分钟内自动构建整个系统并运行测试。极限编程的创立者认为如果团队不能在 10 分钟内完成构建,那么就不太可能频繁的执行构建,因此长时间构建会引入错误。

这个实践鼓励去实现自动化构建以便于日常进行这个操作,并利用这个过程来执行测试。

这个实践可以支持持续集成,本身又被测试驱动开发支持。

持续集成

持续集成的意思是当变更的代码提交到代码库中立即自动运行测试。这个实践的益处是可以尽快发现和修复集成中遇到的问题。

许多团队害怕集成过程的,原因是代码遇到的冲突和其它问题。大部分团队采取的方式是“如果会遇到问题,那就尽量避免”。

极限编程实践者的做法是“如果会遇到问题,那就尽量多做”。

这个方法背后的原因是如果你每次代码集成都会遇到问题并且需要大量时间定位问题,你或许需要更频繁地进行集成。原因是如果会遇到问题,每次集成更少的代码会有助于发现问题。

测试优先编程

传统的开发流程是:
开发代码 -> 编写测试 -> 运行测试

测试优先编程的流程是:
编写暂时无法通过的测试 -> 运行失败的测试 -> 开发代码使测试通过 -> 运行测试 -> 重复以上过程

如同持续集成,测试优先编程缩短了开发人员识别和解决问题的反馈周期,从而减少了引入生产环境的bug数量。

增量设计

增量设计的实践建议您提前做一些工作,以了解系统设计的正确边界,当设计具体功能的时候再深入细节。这个方法减少了变更的成本并且允许你利用现有最多的可用信息来做必要的设计决定。

重构实践本来是列在十二原则之中的,但是被纳入了增量设计实践中。重构是一个优良的实践来保证设计的简单性,另一个受推崇的好处是可以减少流程的重复。

角色

尽管极限编程为您的团队指定了特定的实践,但是它并没有真正为团队中的人员建立特定的角色。

根据阅读过的内容,可能没有关于在传统项目中的常见角色在极限编程项目中的行为方式的指导或描述。以下是四个在极限编程中常见的角色。

客户

客户是负责整个项目业务相关的决定。包括:

  • 系统要做什么事(系统要有什么功能要完成什么事)?
  • 我们如何知道系统已经完成了(系统验收标准是什么)?
  • 我们需要多少成本(可用的预算和商业案例)?
  • 我们接下来要做什么(如何安排功能开发的优先级)?

极限编程的客户应该积极地参与到项目中并成为团队的一员。

极限编程的客户假定是一个人,但通常来说,一个人不足以提供项目所有相关的业务信息。团队成员需要确保了解整个项目的业务图景,并有一些方法来出来其中的矛盾,这样才能有清晰的方向。

开发者

由于极限编程没有明确定义角色,除了客户和下面列出的角色,其他人都被认为是开发者。开发者负责实现客户提出的用户故事。由于不同的项目需要不同的技术能力,同时极限编程的团队是交叉功能的团队,因此极限编程的创建者认为没必要进一步划分角色了。

跟踪者

有些团队的成员包括跟踪者。这个角色通常是某个开发者每周花一定额外的时间来承担的。这个角色的主要目的是持续跟踪一些必要的指标来确定进度,同时明确需要改善的方面。通常主要的团队指标包括开发效率、开发效率变更的原因、超时完成的工作量已经测试的通过情况。

这个角色不是团队中必要的,通常是团队确实需要跟踪某些指标时才有的。

教练

如果你的团队刚刚开始使用极限编程,你会发现有一个团队中有一个教练角色会很有用。这通常是外部顾问或者你组织内其他使用过极限编程的人,由他进入团队来指导团队成员进行实践,并且保证团队成员的纪律性。

这个角色的主要价值在于他已经经历过一些过程,可以帮忙避免大多数团队都会犯的错误。

生命周期

为了描述极限编程的生命周期,可能最好的方式就是重看前面的周循环和季度循环。首先,项目从客户定义的用户故事开始,描述期望的结果。随着这些故事的创建,团队开始预估每个故事的规模。这个规模估计以及客户估计的相对收益可以提供一个相对价值的指示,可以使用它来确定故事的优先级。

如果一个团队由于无法完全掌握完成该故事所需的技术,进而无法预估故事的规模,他们做一些spike以对特定故事或多个故事的共同方面进行一些重点研究。spike是为在项目的特定方面进行研究而预留的短小的时间区间。spike可以在常规迭代之前也可以在正在进行的迭代中。

下一步,团队成员在一起决定一个大家都认为合理的发行计划。发行计划是在特定季度或发行时发布哪些故事的第一步。故事的发布应该基于故事可以提供多少价值以及故事之间的相互支持关系。

然后,团队开启一系列的周循环。在每周循环的开始,团队成员(包括客户)在一起决定这一周要实现哪些故事。团队将故事拆分为任务并在这周内完成。
每周结束时,团队成员和客户回顾这周每日的工作进展,然后决定是否继续进行开发(或软件已经提供了足够的价值)。

起源

极限编程首次被使用是在90年代中期的一个Chrysler Comprehensive Compensation项目中,而且是在Kent Beck进入项目组后为了进行系统优化,才转变为的极限编程。Kent立刻找来了包括Ron Jeffries的几个朋友,改变了团队的开发方式。这个项目将极限编程的方法论引入人们的视野,参与这个项目的人也写了几本书来推广极限编程的知识。

主要贡献

极限编程对软件开发主要的贡献在于提出了一套相互依赖的工程实践,帮助人们开发高质量的代码。许多采用敏捷的团队从使用不同的框架开始,当他们确定需要更严格的工程实践时,就会采用极限编程所倡导的甚至不是全部的几种工程实践。

此外,极限编程所倡导的优质实践也同样重要。该方法规定了少量绝对必要的实践,并鼓励团队尽最大可能执行这些实践。故谓之极限。并不是因为这些实践本身就一定是激进的(尽管有些人认为其中的某些实践还很遥远),而是团队不断专注于不断提高自己执行这几种实践的能力。

参考文献