本文的第一篇阐述了敏捷软件开发的业务目标 —— “可持续的快速交付和稳健的灵活性”,这一目标的实现,需要多个层面的支持。如图(一)所示,业务成功是最终目标,它需要有效开发模式的保障;开发模式的实施又离不开团队组织和技术实践的支撑;最后,通过持续改进、系统优化,获得持久的成功。这一层次关系中,外层是内层的目标,内层为外层提供支持。
图(一) 由外而内看敏捷
本系列文章将按照图中所标示的五个部分,由外而内分别阐述敏捷软件开发的各个方面。这也是文章题目(由外而内看敏捷) 的来源。本篇将探讨敏捷软件的开发模式。与前一篇相同,我们还是会增量的提交观察报告。
软件开发的任务是“提供方案以解决用户问题”。软件开发的过程就是通过有组织的活动,实现从“问题域”到“解决方案域”的转换过程。开发团队究竟是以问题域为核心展开开发过程,还是以解决方案域为核心展开开发过程?在这一点上传统开发软件方法和敏捷软件开发方法是不同的,其效果也有很大差别的。
图(二)问题域到解决方案域的映射过程 —— 传统模式
图(二)反映了传统软件开发模式下,从问题域到解决方案域的映射过程。其典型特征是:“在解决方案域内分解系统,围绕解决方案域展开开发过程”。首先,业务分析人员获取和分析用户的需求,完成初步规格说明;然后,架构设计人员依据规格说明在方案域内将任务分解到各个软件代码模块,并分配至不同的开发人员;再由他们分别实现各个模块的编码、测试;最后完成系统的集成验证,实现最终解决方案。
这一模式无法满足敏捷软件开发中快速迭代交付价值、灵活响应变化,以及与客户紧密合作的需要:
系统在解决方案域内被分解成各个模块的工作,所有模块完成后才能进行系统集成和验证,无法分步完成和迭代交付产品功能。
工作在解决方案域内被分解后,所有需求的开发同步开始。在整个开发过程中,功能一直处于半成品状态,如待实现的设计、待集成的编码和待验证的集成等。其间,对需求的任何变更、增加或删除,都意味着对这些半成品的返工,缺乏应对变化的灵活性。
该模式下,用户和业务人员工作在问题域,从问题域出发,思考、描述和沟通问题;开发人员工作在解决方案域,从解决方案域出发,思考、描述和沟通方案,缺乏同用户及业务人员的共同语汇和沟通场境,无法建立和用户的心智联接。在体验为王的今天,这恰恰是决定产品竞争力的必备要素。而且每一个开发人员接触和负责的只是解决方案的一个局部,而非用户的原始问题,这样,会造成闭门造车和局部优化,丧失针对问题的创新机会。
图(三)问题域到解决方案域的映射过程——敏捷模式
与传统软件开发以方案域为核心不同,敏捷开发以问题域为核心。图(三)反映了敏捷软件开发模式下,从问题域到解决方案域的映射过程。其典型特征是:“在问题域内分解系统,围绕问题域展开开发过程”。如图所示,用户、业务人员与开发团队充分沟通,需求在问题域内被拆分成端到端的子项;同一时间段,整个开发团队围绕一小部分用户需求,紧密协作,完成设计、开发和集成、验证工作,生成一个可运行的、满足部分需求的完备系统,并基于它获取用户和业务人员的反馈。系统逐步增长,直至交付全部解决方案。这一模式有效应对了前面提到的问题,也即,迭代交付价值、灵活响应变化、以及建立开发者和用户间的心智联接。
第一次提交“从开发模式看敏捷”的观察报告
从开发模式看敏捷 - 敏捷软件开发模式下,开发过程围绕问题域展开,在问题域内分解系统,以利于迭代交付价值,灵活响应变化,并建立开发团队和用户之间的心智联接 … |
图(四)项目决策时间模型 —— 传统模式
软件开发是一个知识创建的过程,随着开发进程的推进,团队逐步积累业务需求、市场环境、技术方案、实现技术等方面的知识。如图(四)所示,团队拥有最丰富知识的时刻是在项目的末期,这也是最能做出正确决策的时刻。然而,与之对应的是,在传统软件开发模式下,绝大部分的决策是在项目的早期做出,如:设定产品需求、承诺项目计划和确定架构方案等。此时的决策只能依据十分有限的团队知识,其质量必然是有问题的,却要成为后期项目执行的依据和约束。过早的决策也为其后的需求、技术和计划变更引入不必要的成本,这显然是不合理的。
图(五)项目决策时间模型 —— 敏捷模式
敏捷软件开发倡导“延迟决策”。如图(五)所示,在项目开发进程中,市场和技术环境发生变化;客户对自己的需求的认知更加清晰;成员对业务和技术的掌握更加全面深入。团队各方面的知识不断增长。对应的,项目的决策也是分步做出的,在项目启动阶段团队做出了一些基本的决策,更多的决策是在每个迭代中做出的。为更好的做到延迟决策,并提高决策的有效性和质量,敏捷开发团队需要做到:
决策不可能无限期的延迟。问题是,何时是最佳的决策时间?答案是“最后责任时刻”(The Last Responsible Moment)[1],这时再不做决策,将失去一个重要的决策选项,或者因时间点到了,系统将选择缺省方案(如不采取动作,或沿用既有方式等),这往往也不是最好的决策。
对于不同类型的决策,其“最后责任时刻”也是不同的,例如:每个迭代要完成的内容及其相关计划,在迭代开始的时候才最终确定,具体实现方案在实现时确定。而项目的总体目标,实现语言和框架的决策,很可能在第一个迭代前就需要做出。
刻意的发现(Deliberate Discovery)是由Dan North提出。他指出项目启动时,团队缺乏业务领域、构建技术、遗留代码、工具等方面的知识,处于对项目最无知的状态,其中也包含对无知的无知。无知是项目开发进度和质量的最大制约。被动的、基于已有知识决策是不够的。团队应该在开发过程中,通过有计划的活动,刻意的去探索发现,以最快和最大化的消除影响项目进展的无知。这一过程被称为刻意发现的过程,它加速了软件开发的知识创建过程,同时为项目决策提供知识和技能的支持。
在敏捷软件开发中,风险驱动的计划,技术探索需求(spike story), 早期的反馈,探索性的测试,演进式设计都属于刻意发现的过程,它们有力的支持了项目在执行、技术,以及商务上的成功。
适当技术实践的采用可以更好的支持延迟决策。例如,低耦合的架构模式的采用,有利于延迟架构和设计的决策;更加易于修改和验证的代码,降低了需求决策延迟的成本;接口和实现分离,使底层细节的决策可以尽量延迟;持续重构,增加了系统实现上延迟决策的可能性。这方面内容将在技术实践部分作更详细的讨论。
第二次提交“从开发模式看敏捷”的观察报告
从开发模式看敏捷 - 敏捷软件开发模式下,开发过程围绕问题域展开,在问题域内分解系统,以利于迭代交付价值,灵活响应变化,并建立开发团队和用户之间的心智联接 - 敏捷软件开发在开发过程中积累业务、产品和技术方面的知识,延迟决策,并通过刻意的知识发现过程,来提高决策的有效性和团队的价值交付能力 … |
迭代开发模式[2]是指,把整个开发过程划分成多个连续的迭代,每个迭代都是包含需求、设计、实现和测试的完整过程,并产生可以验证概念或交付的软件。迭代开发模式的出现远早于敏捷软件开发方法的出现[3],敏捷的迭代开发模又有什么特点呢。
图(六)敏捷的迭代开发模式
图(六)概括了敏捷的迭代开发模式(至少涵盖XP 和 Scrum 方法)—— 在每个时间盒内,完成一部分端到端的产品功能,生成潜在可交付的产品增量的演进式开过程。时间盒,潜在可交付的产品增量,演进式开发过程是敏捷的迭代开发模式的三个核心概念。
大多数敏捷开发方法都采用固定时长的迭代周期,也就是所谓时间盒,它是指,1)固定迭代的开始和结束时间;2)当迭代结束时间到达时,无论在何种情况下都终止迭代;3)每个迭代的时间是等长的。Scrum的典型时间盒长度为2到4周,XP的典型时间盒长度是1到2周。其意义在于:
时间、内容和资源是软件开发的三要素。敏捷项目中,资源是相对固定的。 通过定长的时间盒,时间要素也被固定下来。这样每个迭代要操纵的只有内容一个要素了。也即,每个时间盒内,规划和完成适量的内容。时间盒形成了开发的节拍,在操作上简化了计划和跟踪的复杂度,同时,改善了项目的可预测性。
帕金森定律是指,“不管有多少时间,工作都会扩展,直至耗尽所有的时间”。在以产品开发阶段定义里程碑的项目中,几乎总能看到帕金森定律的作用。这也被称为学生综合症 —— “一定要等到考试前一刻,才能结束功课的复习”。
短的固定长度的时间盒,将迫使团队,在一段时间,聚焦在有限的功能。相比几个月后的里程碑,一到数周后的交付目标显然更容易引发重视和紧迫感。一方面,这降低了项目进度风险发生的可能;另一方面也降低了进度风险发生时的影响,项目结束时,至少可以交付已完成迭代的内容,相对错过最终的发布周期,如期交付80%内容(通常也是最重要的80%),显然是更成功的。
每个时间盒完成一部分功能,展示和交付相对应的软件,可以确保团队得到周期性的反馈。包括外部反馈如:产品内容与客户的需求一致吗? 目前产品的外部质量如何? 产品开发的进度是否能满足项目目标? 内部反馈如:团队的沟通合作是否存在问题? 产品的技术方案,能否满足功能需要?开发技术实践和基础实施满足项目的需要吗?
在敏捷的迭代开发模式下,每个迭代产生有价值的产品增量。它是包含部分需求的完备产品,是稳定的、被集成和测试的,达到向客户交付的要求。这通常被称作潜在可交付的产品增量(PSPI, Potential Shippable Product Incremental)。每个迭代能否产生潜在可交付的产品增量,是敏捷的迭代开发模式执行效果的重要衡量,它的意义在于:
虽然是否每个迭代都交付产品,还要受于产品的形态,以及客户习惯的制约。但是,每个迭代产生潜在可交付的产品增量,使尽早实现业务价值成为可能。此外,每个迭代完成相关功能所有开发、测试及相关内容,不将部分完成的工作遗留到下面的迭代。这样在后面的迭代中,只需要考虑即将开发的内容,为内容和开发计划的调整提供了便利,加强了业务调整的灵活性。
从需求确认开始,直至需求的可交付,每个迭代都是一个全过程的开发周期,产生完整的业务和技术反馈,不管是业务需求、技术实践,还是团队合作、开发过程以及研发基础设施等方面的问题,只要阻碍了价值交付,都将被暴露。通过解决这些问题,团队端到端的价值交付能力得以提高。
此外,每个迭代都达到可交付的质量标准,在开发过程中内建质量,而不让产品的质量和进度依赖于最后的测试阶段。这为产品质量、开发进度衡量的可靠性性,和开发过程的可预测提供了保证。
将开发过程划分成时间盒,每个时间盒交付有价值的增量。但如果需求、计划、架构都在前期设定,这只是增量开发,而不是迭代开发,更不是敏捷的迭代开发。迭代开发的本质在于,在开发过程中通过不断的反馈、调整,逐步完善产品的功能定义、开发计划,以及设计实现。
如前面所述,软件开发是一个创造和知识发现的过程。一步到位的计划和方案是行不通的。在开发过程中,团队得到来自市场、客户、其它利益相关方,以及开发过程自身的反馈。相应的,团队需要对产品内容、技术方案、项目估计和项目计划等做出即时的调整,有效利用这些反馈,适应市场及技术环境,即时响应客户的需求变化,改进目标产品和项目实践,演进式的推进开发过程。
迭代和演进式开发的思想和实践一方面体现在迭代周期之间,如每个短的迭代周期结束,展示完成的功能,获取反馈,并调整进一步需求,以及开发计划,更好的满足用户;另一方面体现在整个开发过程中(包括迭代内部),如通过重构不断优化设计,并提供更简洁和合适抽象,又如,测试驱动开发本身就是一个更微观的迭代过程,通过不断的“测试à开发à重构”的循环过程,演进的完成最后适合的方案。
至此,我们可以提交从开发模式看敏捷的完整观察报告了
从开发模式看敏捷 - 敏捷软件开发模式下,开发过程围绕问题域展开,在问题域内分解系统,以利于迭代交付价值,灵活响应变化,并建立开发团队和用户之间的心智联接 - 敏捷软件开发在开发过程中积累关于业务、产品和技术方面的知识,延迟决策,并通过刻意的知识发现过程,来提高决策的有效性和团队的价值交付能力 - 敏捷软件开发遵循迭代和增量的开发模式,在每个时间盒内产生潜在可交付的产品增量,通过不断的反馈调整,演进式推进产品的开发过程 |
敏捷开发模式为敏捷开发的业务目标提供了有力保障。同时,敏捷开发模式的实施离不开团队组织和技术实践支持。下一篇中,我们将讲述在敏捷开发模式下,如何有效组织开发团队。
[1] 最后责任时刻(The Last Responsible Moment)是来自精益生产的概念,Mary Poppendieck 最早在“Lean Software Development: An Agile Toolkit”一书中把这个概念引入软件开发领域。
[2] 自2006年看板(Kanban)开发方法诞生以来,敏捷开过程包含了基于流(flow based),和基于迭代(iteration based)两类方法体系。基于流的开发方法中,被比较广泛采用的只有看板一种,对于它的讨论超出了本文的范围,更多细节请参见:http://agilemanagement.net/index.php/Blog/the_principles_of_the_kanban_method/。对两种方法体系的比较将另文讨论。
[3] 关于迭代软件开发模式的历史,请参见Craig Larman 的文章 Iterative and Incremental Development: A Brief History