极限编程中的关联性分析
2021-01-22郭峰
郭峰
(北方工业大学信息学院,北京 100144)
0 引言
在软件开发过程中,需求变更几乎是不可避免的,传统的软件过程模型对于需求变更虽然采取了刚性的措施,最早的瀑布模型要求在需求分析阶段把需求固定下来,之后不可有变化,体现了对需求变更的不友好甚至是排斥的态度。RUP[1]做为传统软件过程模型的集大成者,完美体现了软件工程系统、规范、可度量的特点,采取迭代、并发等多种措施解决需求的变化问题,但仍然是被动消极的应对方案。在中小型项目中,应用RUP通常存在一定的困难,最典型的问题是按照RUP模型,在整个软件生命周期内,大部分时间多个任务并发执行,中小型项目在人员分工管理方面通常不足,无法满足RUP模型的要求。
2001年2月17位著名的软件专家联合起草了敏捷软件开发宣言,标志着敏捷方法的出现。“敏捷”一词意味着快速、简单、灵活,敏捷方法代表了一种积极的态度,经典的敏捷方法书籍《解析极限编程》的副标题是拥抱变化[2],与传统的软件过程模型被动消极的态度不同,敏捷方法不排斥需求的变化,强调积极面对需求的变化,采用柔性的手段,通过过程、管理以及实践尽可能满足用户的需求,不看重以合同的形式分割需求的界限。敏捷开发的基本理念是以最简单有效的方式快速地完成开发任务,在开发过程中针对需要及时响应的外界变化迅速做出调整。
敏捷软件开发方法不是一个具体的方法,而是一个涵盖性术语,用于概括那些应需而生的具有类似价值观的软件开发过程和开发方法,这些方法通常都具备以人为本、循环迭代、响应变化等特征,更注重能高质量地快速交付客户满意的软件产品,而不强调规范严谨的过程和面面俱到的文档。代表性的敏捷软件开发方法有:极限编程、SCRUM、特征驱动软件开发、动态系统开发、自适应软件开发、Crystal等[3]。
1 极限编程概述
敏捷方法是一类方法的统称,极限编程属于敏捷方法中的一种,获得了较为广泛的关注,并在实践中获得大量的应用。极限编程是一个轻量级的、灵活的软件开发方法,同时它也是一个非常严谨和周密的方法。极限编程包括价值观、原则和实践三个部分。极限编程的基础是4个价值观念:
沟通-大多数项目的失败可归结于沟通不畅,开发人员之间、开发人员和客户之间都需要积极的多种渠道的沟通,敏捷方法在提高客户的参与度、增加开发人员的沟通途径、采用高效率的会议等方式提高沟通的质量。
简单-敏捷方法强调效率和实用性,首要目标是开发能够满足客户需要的最简单的产品,需求分析、结构设计、编写程序和文档的工作尽可能简化,避免过度分析过度设计等现象。
反馈-反馈可以让开发者把握正确的方向,少走弯路。开发者要获取来自客户、系统和其他开发者的反馈,并基于反馈改进分析、设计和实现。
勇气-开发人员对于放弃系统的代码、改进系统设计等行为通常是谨慎的,敏捷方法强调在必要的时候果断做出决策。
极限编程在表现形式上是一组简单、具体的实践,这些实践结合在一起形成了一个敏捷开发过程,项目团队可以直接采用这些实践,也可以增加一些实践,或者对其中的一些实践进行修改后再采用。极限编程在刚刚提出的时候,人们普遍认为它仅适合小型软件项目的开发,而目前也可将其应用于大中型软件项目之中。
极限编程的价值观是极限编程的指导思想,实践是具体的做法,原则是两者之间的桥梁,原则依据价值观指导实践,是对价值观的具体的解释。极限编程的原则包括人性化、经济学、互惠互利、自相似性、改进、多样性、反省、连续性、机遇、冗余、及时决策、关注质量、小步前进、接受责任等。
2 极限编程实践的关联性分析
敏捷方法的价值观是:(1)个体与交互重于过程与工具;(2)可以工作的软件重于面面俱到的文档;(3)与客户的合作重于与其合同的谈判;(4)对变化的响应重于对计划的遵循。极限编程的价值观是沟通、简单、反馈、勇气。两者的价值观是互通的,是从不同角度的阐述。
图1 极限编程的实践对需求变更支持的强度
敏捷方法以及极限编程要解决的一个重要问题就是积极、灵活、有效地处理需求变更。极限编程的核心是12条实践,这些实践作为一个整体体现敏捷方法和极限编程的原则和价值观。如平稳的工作效率体现人性化的原则,更容易使开发人员长期保健康的心理和生理状态,有利于软件质量的提高。现场客户体现与客户的合作重于合同的谈判的价值观。简单设计体系可以工作的软件重于面面俱到的文档。毫不留情的重构体现勇气这一价值观,代码规范、测试驱动开发、集体拥有代码相互关联,才可以保证重构的质量。持续集成、小版本发布使得用户能够尽早发现问题,是响应变化的有效措施。
极限编程的实践有些直接支持需求变更,有些对其他实践形成支撑,从而间接支持需求变更。图1描述了这些实践与需求变更的关系,与需求变更的距离越远表示实践对需求变更的支持强度越低。
在传统的软件项目中,客户一般不全程参与软件开发过程,客户的任务通常只包括讲解需求,测试和验收软件系统。在极限编程中,现场客户实践要求客户始终参与软件开发,并为客户增加以下任务:编写用户故事(User Story),评估用户故事的商业优先级,为每个用户故事设计测试用例,参与开发计划的制订,参与开发过程的调控。通过提高客户的参与度,可以更有效地解决需求变化问题。频繁发布实践可以保证客户能够有充分接触待发布产品的机会,从而可以获得充分的用户反馈,并以此为依据调控开发过程(通过增加、删除或改变用户故事来实现),在频繁发布的过程中,所有的发布都要经过功能测试,可有效降低开发风险。计划游戏的含义是项目计划建立起来以后,需要根据项目的进展来进行调整。这三条实践直接支持需求变更,其他实践通过相互关联和呼应间接支持需求变更,图2描述了极限编程12条实践之间的关联关系,图中箭头表示一条实践对另一条实践形成支持。
隐喻使得所有项目参与人员都对相关的抽象概念有统一的、具体的认识,有助于相关人员的沟通,良好的沟通尤其是与客户的沟通是明确需求的有效路径。图中只描述了隐喻对现场客户的支持,实际上对其他实践也存在支持关系,在与客户沟通过程中隐喻的作用更大一些。
极限编程提倡毫不留情的重构(Refactor mercilessly)。由于集体拥有代码,因此任何人有权利重构任何代码,只要保证重构后的代码100%通过单元测试即可。仅仅从重构的名称上来理解这一条实践是远远不够的,在代码规范、结对编程、集体拥有代码以及测试驱动开发的基础上才有可能做到极限编程提倡的毫不留情的重构,否则一定要谨慎地对待重构。
计划游戏意味着开发计划的调整,需要简单设计和现场客户的支持,简单设计形成的设计方案往往是不完善的,基于不完善的设计方案编写的代码需要重构,因此简单设计需要重构的支持。
图2 极限编程12条实践之间的关联关系
通过结对编程集体拥有代码才有可能实现,持续集成支持频繁发布,现场客户和频繁发布相互支持,集体拥有代码支持持续集成和重构。测试驱动开发、结对编程、集体拥有代码、重构都需要代码规范的支持。代码规范是一个很宽泛的概念,但是在极限编程中,代码不规范将使多个实践受到影响。
通过这些实践相互关联相互呼应,才可以对需求变更不采取排斥的态度,真正做到“拥抱变化”。上述实践作为一个整体形成极限编程方法,某些方法本质上不是极限编程特有,比如编程规范,在任何软件项目中都应该遵循,测试驱动开发目前已经称为流行的软件开发模式,但是由于这些实践之间存在关联关系,只有这些实践的全部或者大部分都在项目中得以应用,才能发挥极限编程的作用。
3 结语
学习和应用极限编程,通常从12条实践入手,这些实践往往可以在软件开发过程中独立应用,但是孤立地应用一条或几条实践不能有效地发挥其作用,这些实践相互呼应,才能实现拥抱变化的初衷。本文分析了极限编程12条实践之间的关联性,有助于读者在实际软件项目开发中更好地学习和应用极限编程,以提高软件的质量以及开发的效率。