敏捷开发 - 面向工程管理:极限编程(XP)

极限编程(ExtremeProgramming,简称XP)是由KentBeck在1996年提出的,是一种软件工程方法学,是敏捷软件开发中可能是最富有成效的几种方法学之一。XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期;通过积极的交流、反馈以及其它一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。极限编程透过引入基本价值、原则、实践方法等概念来达到降低变更成本的目的。@pdai

什么是极限编程?

来源于百度百科在新窗口打开:极限编程(ExtremeProgramming,简称XP)是由KentBeck在1996年提出的,是一种软件工程方法学,是敏捷软件开发中可能是最富有成效的几种方法学之一。如同其他敏捷方法学,极限编程和传统方法学的本质不同在于它更强调可适应性能性以及面临的困难。1996年三月,Kent终于在为DaimlerChrysler所做的一个项目中引入了新的软件开发观念——XP。适用于小团队开发。

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

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

极限编程的目标

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

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

极限编程的价值观

极限编程主要包含如下价值观。

沟通(Communication):XP 方法论认为,如果小组成员之间无法做到持续的、无间断的交流,那么协作就无从谈起,从这个角度能够发现,通过文档、报表等人工制品进行交流面临巨大的局限性。因此,XP 组合了诸如对编程这样的最佳实践,鼓励大家进行口头交流,通过交流解决问题,提高效率。

简单(Simplicity):XP 方法论提倡在工作中秉承“够用就好”的思路,也就是尽量地简单化,只要今天够用就行,不考虑明天会发现的新问题。这一点看上去十分容易,但是要真正做到保持简单的工作其实很难的。因为在传统的开发方法中,都要求大家对未来做一些预先规划,以便对今后可能发生的变化预留一些扩展的空间。

反馈(Feedback):通过持续、明确的反馈来暴露软件状态的问题。具体而言就是:1、在开发团队内部,通过提前编写单元测试代码,时时反馈代码的问题与进展。2、在开发过程中,还应该加强集成工作,做到持续集成,使得每一次增量都是一个可执行的工作版本,也就是逐渐是软件长大,整个过程中,应该通过向客户和管理层演示这些可运行的版本,以便及早地反馈,及早地发现问题。

勇气(Courage):在应用 XP 方法论时,由于沟通良好,因此会有更多需求变更的机会;由于时刻保持系统的简单,因此新的变化会带来一些重新开发的需要;由于反馈及时,因此会有更多中间打断你的思路的新需求;处于变化之中,因此这时就需要有勇气来面对快速开发,面对可能的重新开发。XP 方法论让问题早出现、早解决,是实现“小步快走”开发节奏的好办法。

极限编程的原则

极限编程包含5个原则

快速反馈:及时地、快速地获取反馈,并将所学到的知识尽快地投入到系统中去。也就是指开发人员应该通过较短的反馈循环迅速地了解现在的产品是否满足了客户的需求。这也是对反馈这一价值观的进一步补充。

简单性假设:类似地,简单性假设原则是对简单这一价值观的进一步补充。这一原则要求开发人员将每个问题都看得十分容易解决,也就是说只为本次迭代考虑,不去想未来可能需要什么,相信具有将来必要时增加系统复杂性的能力,也就是号召大家出色地完成今天的任务。

逐步修改:不要一次做出很大的改变,那样将会使得可控性变差,更适合的方法是进行微调。而在软件开发中,这样的道理同样适用,任何问题都应该通过一系列能够带来差异的微小改动来解决。

提倡更改:在软件开发过程中,最好的办法是在解决最重要问题时,保留最多选项的那个。也就是说,尽量为下一次修改做好准备。

优质工作:在实践中,经常看到许多开发人员喜欢将一些细小的问题留待后面解决。例如,界面的按钮有一些不平整,由于不影响使用就先不管;某一两个成员函数暂时没用就不先写等。这就是一种工作拖泥带水的现象,这样的坏习惯一旦养成,必然使得代码质量大打折扣。在 XP 方法论中,贯彻的是“小步快走”的开发原则,因此工作质量决不可打折扣,通常采用测试先行的编码方式来提供支持。

极限编程的实践

XP实践包含三个闭环的圈,最里面的环围绕个人如何编码和设计;中间的环围绕作为团队如何协作编码和集成;最外围的环面对客户如何协作、计划和交付。

最外环: 面对客户如何协作、计划和交付

完整团队(Whole Team)

XP团队是一个跨职能团队,拥有项目或产品成功所必需的各种技能和视角的人,包括现场客户(On-site Customer)或者真实用户(Real CustomerInvolvement)、开发人员和测试人员等。如果客户不能和团队天天工作在一起,那么需要客户定期参与计划会议,同时需要业务代表(Business Representative)来代表客户,也被称为产品经理(Product Manager),统称为客户(Customer)。客户负责提供和编写需求(用户故事)、排定需求优先级、调整需求范围等以此掌控产品方向。团队面对面地坐在一起办公(Sit Together);为了促进透明的面对面沟通,会建立信息化工作空间(Informative Workspace),通常采用可视化或者信息雷达的方式将产品、架构、计划、进度等展示出来;团队每周工作40小时,充满活力地工作(Energized Work)。

计划游戏(Planning Game)

XP团队按每周周期(Weekly Cycle)进行迭代计划会议(Iteration Planning),同时按照季度周期(Quarterly Cycle)进行发布计划会议(Release Planning)。发布计划是当前对发布内容及日期的快照,当计划赶不上变化的时候,就更新这个计划,以便反映客户最新的期望。使用故事(Story)作为客户或用户可见、有意义的功能单元进行计划,故事也被称为用户故事(User Story),这些故事旨在从用户视角简要描述用户希望能够使用产品及与产品交互的功能及目标,并在团队实现特定故事时,提醒团队进行更详细的对话。

小版本(Small Releases)

每个版本都应尽可能小,包含最有价值的业务需求,并且通过增量部署(IncrementalDeployment),甚至每日部署(Daily Deployment)来尽可能地频繁发布到终端用户手中,这意味着需要在每个迭代结束后交付给客户经过测试的、可以运行的软件,以便客户进行评估或者发布给用户。

客户测试(Customer Tests)

作为呈现每个所需功能的一部分,XP客户针对每个用户故事定义了一个或多个验收测试(Acceptance Test),以判断该功能是否能正常运行。团队构建这些验收测试用例的脚本,并使用它们向自己和客户证明该功能是否正确实现。自动化非常重要,因为在时间紧迫的情况下,会跳过手动测试。

中间环:团队如何协作编码和集成

持续集成(Continuous Integration)

团队的成员经常集成他们的工作,通常每个成员每天至少集成一次,这导致每天发生多次集成。每次集成都通过自动化的构建(包括测试)来验证,从而尽快地检测出集成错误。XP团队提倡一旦代码发生改变就签入单个代码库(Single Code Base),也就是一个主干,并立刻触发自动化的测试,并应用十分钟构建(Ten-Minute Build),即在十分钟之内自动地构建整个系统和运行所有的测试。

代码集体所有制(Collective Ownership)

团队中的任何人都可以随时改进系统的任何部分、任何代码。如果系统出了问题,修复它并没有超出我现在所做的范围,我应该继续修复它。这意味着所有代码都可以获得许多人的关注,从而提高代码质量并减少缺陷。这也意味着所有的代码都是共享的代码(Shared Code)。

编码标准(Coding Standard)

XP团队遵循通用的编码标准,因此系统中的所有代码看起来都像由一个非常称职的人编写的。标准的细节并不重要,重要的是所有代码看起来都很熟悉,以支持代码集体所有制。

可持续的步调(Sustainable Pace)

也称为团队可持续性(Team Continuity),团队长期、持久地参与产品开发中,能够以长期、可持续的速度努力工作。可持续就像马拉松赛跑,这样可以保持一定程度的松弛(Slack)。在任何计划中,都要包括一些小任务,如果你落后了,这些任务就可以取消,但不影响最初的承诺,毕竟,履行你的承诺在任何时候都是很重要的。而相反的是全速赛跑,因为死亡行军(Death March)既没有生产力也没有高质量的代码,也不能兑现承诺。

最内环:个人如何编码和设计

简单设计(Simple Design)

XP团队使他们的设计尽可能简单,仅仅关注本次迭代中要完成的用户故事,团队更愿意在迭代中不断地演进系统的设计,甚至每天都考虑系统设计来进行增量设计(Incremental Design),力求使得系统设计适应当天的系统需求。XP中的设计不是一次性的事情,也不是一个前瞻性的事情,它是一个永远持续的事情。同时,XP团队对他们根据未来需求调整设计的能力充满自信。良好的设计至关重要,这就是为什么在整个开发过程中如此关注设计。

结对编程(Pair Programming)

所有的代码都是由两个程序员并排坐在一起,使用同一台机器、同一个键盘和同一个鼠标编写的。这种做法是确保使用键盘和鼠标的程序员思考编码的最佳途径,另一名程序员偏重于从战略性的角度思考并评审所有代码,从而实现更好的设计、更好的测试和更好的代码。结对的关系要经常变换,每天至少要改变一次,从而结对编程还可以极大促进知识在团队中的传播。

测试驱动开发(Test Driven Development)

也叫作测试先行编程(Test-First Programming),在改变任何产品代码之前先编写一个自动化测试代码。极限编程痴迷于反馈,在软件开发中,良好的反馈需要良好的测试。首先编写一段单元测试代码,由于它要测试的产品功能代码还不存在,所以它会运行失败;然后编写产品功能代码使测试通过。

重构(Refactoring)

就是在不改变代码外部行为的前提下,对其进行一系列小的改造,消除重复代码,保持代码的高内聚和低耦合,使得产品功能代码更简单,未来添加新的代码更简单,从而达到防止代码腐化、支持简单设计的目的。同时,应用测试驱动开发,确保每次产品功能代码的改动,其对应的单元测试脚本都得以通过,并且随着设计的发展,没有功能被破坏掉。

极限编程的开发过程

针对实际结合XP的开发过程,此外我在整理时找到CSDN博主「码农老张Zy」在新窗口打开的一张图(应该是来自XP相关的书籍,没有具体考证)。

XP 的生命周期就如下图所示。

在这个图中,我们看到了 用户故事 ,注意,它很重要,在敏捷中,需求都会定义为 用户故事 ,关于它的内容我们后面还会学到。然后就是根据 用户故事 定义的 发布计划 。我们会在 发布计划 中包含 总体估算 和 隐喻 。在这里,需要记住的是敏捷中的估算都是相对估算,都是不精准的。

接下来,我们会根据 发布计划 和 用户故事 来确定每个 迭代中需要做的事情,也就是 迭代计划 。在这个计划中,通过客户对功能的解释会将 用户故事 进行更加深入的拆分,变成任务。之后就是通过 结对编程 来实现我们的产品。

当 迭代 结束时,或者到了 发布计划 制定的发布结点时,我们就需要通过 小规模发布 来实现产品的迭代、增量开发,从而达到敏捷的能力。

上述几个步骤,就是一个 XP 项目开发的整个生命周期过程,完整的产品最后就是通过这样不停地迭代实现的。在图中,我们还看到了 架构探针 和 探针 这两个东西。其实,它们是为了些特殊情况而使用的,比如说采用了新的技术、或者使用了新的架构、或者我们第一次尝试 XP 开发。这个时候,一个探针就像是一次测试的微型迭代。探针 是为了减少风险的,并且可能在整个项目开发中经常会使用到。

参考文章

本文主要总结梳理自:

https://baike.baidu.com/item/%E6%9E%81%E9%99%90%E7%BC%96%E7%A8%8B/4690591

https://blog.csdn.net/zhangyue0503/article/details/121092466

https://yydatav.blog.csdn.net/article/details/118112175

https://blog.csdn.net/wj123dd/article/details/80266495

https://blog.csdn.net/zhangyue0503/article/details/121092466

Extreme Programming: Values, Principles, and Practices在新窗口打开

https://www.altexsoft.com/whitepapers/agile-project-management-best-practices-and-methodologies