敏捷软件开发方法受到越来越多的关注。图(一)是来自Google 趋势的数据,它反映了近年来Scrum(敏捷开发方法的典型代表)和 CMMI(传统开发方法的典型代表)的相对搜索量变化趋势比较。在2004年CMMI的搜索量还是Scrum 的接近3倍,2007年Scrum的搜索量第一次超过CMMI。时至今日,Scrum的搜索量已超过CMMI三倍。

图1 Scrum 和 CMMI相对搜索量的趋势比较

这只能说明一个问题 —— 敏捷很火!问题是,它应该是你的选择吗?先听听别人怎么说,培训机构说:“它是两天的培训”;咨询公司说:“你需要贴身辅导”;工具提供者说:“你out了,该升级啦”; PMI说:“我们也敏捷了,第一期敏捷项目管理认证马上开始”[1];SEI说:“CMMI也敏捷了,我们已经在CMMI 1.3版中为重要的KPA(关键过程域)添加了敏捷的标签”[2];还有人说:“敏捷是神马?”。

敏捷被赋予了太多的含义,甚至承载了利益,有时还让人迷惑。本文并不试图去定义敏捷。但,我们会分别从外部(业务视角)和内部(开发模式及组织视角)观察正在发生的敏捷,并提交观察报告。

从外部(业务视角)看敏捷

离开用户的价值、离开组织的业务目标去谈开发模式的转变只有两种可能——“自以为是”或“别有用心”。我们对敏捷的观察将首先从业务目标出发——从外部看敏捷。

1. 反摩尔定律 ⇒ 速度关乎生死,增量交付价值

IT从业者都知道“摩尔定律”——同样的钱所能买到的产品性能,将每隔18个月翻两倍。Google的前CEO 埃里克? 施密特在一次采访中指出,如果你反过来看摩尔定律,一个 IT 公司如果今天和十八个月前卖掉同样多的、同样的产品,它的收入就要降一半,在IT领域这被称为“反摩尔定律”。反摩尔定律告诉我们,同样的产品所能获得的价值,随时间按一定斜率下降。更有甚者,错过了一个时间窗口,产品可能就不再有任何价值。产品推出的迟早,不仅影响获得回报的时间,还影响到获得价值的多少,甚至是有无。

在竞争激烈和复杂多变的市场环境中,快速把概念转化为产品推向市场的能力事关组织的生死。然而,做到这一点并不容易。增加人手?受资源制约。而且,因沟通复杂度的增加可能反使项目延期,这一点在《人月神话》中早有论述。提高开发效率?那不是一朝一夕的事情,敏捷开发实施也不直接带来开发效率的提高。

敏捷软件开发的应对之道是改变价值的交付模式。如图(二)所示,在以瀑布模型为代表的传统开发模式下,只在项目开发完成时一次性交付全部的价值,在此之前的产出都是半成品。敏捷软件开发倡导迭代和增量的价值交付模式,如图(三)所示,在敏捷软件开发模式下,产品开发进程被划分成固定时长的短迭代周期,每一个迭代产出潜在可交付的产品增量,产品的一部分价值得以实现。

图2 瀑布模型下的价值实现

图3 敏捷模式下的增量价值实现

为了做到价值的增量交付,需求要被拆分成小的端到端可交付单元。同时,小的需求便于沟通,团队、业务人员以及客户,更容易对特定需求进行深入、具体的讨论和澄清。小的需求也便于管理,可以灵活地安排迭代计划,在图(三)的价值实现的阶梯中,越是靠前的迭代,交付的价值越大。优先实现高价值的需求,在迭代开发模式下,是一个很自然的选择,这样组织可以在最短的时间获取尽可能多的价值。

后面我们还会看到,迭代和增量开发模式影响的不仅是价值交付的模式,它还是很多其它敏捷实践(如及时的策略调整,风险消除等)的前提。

我们可以开始交付我们的观察报告了,当然,它也会是增量交付的。

从外部(业务视角)看敏捷

- 敏捷软件开发遵循迭代和增量的开发模式,以尽快实现和交付用户价值

- ……

2. Netscape之死 ⇒ 增量交付还不足够,可持续才有意义

Netscape(网景)死了, 2007年AOL宣布将停止对Netscape的支持。90年代的互联网用户还会怀念它,它最高时占据了浏览器市场86%的份额。Netscape 的衰落有很多原因,众所周知的是微软利用了它在操作系统市场的优势。回顾这段浏览器大战的历史,特别是最关键的1997年到2001年,会有一些其它的发现。

1997年6月Netscape推出了Netscape4.0,其后差不多三年半的时间里,Netscape没有推出过一个主要版本,而微软先后推出了突破性的IE4.0和IE5.0,取得完胜。图(四)来自“Practices for Scaling Lean & Agile Development”一书,很好地展示了在这段时间浏览器版本的推出和市场份额变化的关系。

图4 浏览其市场份额及其版本

难以置信,在1997 - 2001这三年多的时间里Netscape在做什么?微软在1997年底推出了IE4.0,1999年推出IE5.0,在功能上全面超越了Netscape 4.0,而此时Netscape 4.0却不得不面对越来越多的奇怪的Bug。更严重的是,Netscape的代码是如此之糟糕,以至团队认为,再也无法基于它做重大的修改了。为此,Netscape 做出了一个重大决定 —— 重写代码。2001年初Netscape 终于推出了6.0(从来没有过5.0),但这时Netscape的市场占有率已经降到了5%以下,这场浏览器大战胜负已决。

这是一个悲情的故事,Netscape的工程师们绝望地看着Netscape的市场份额急剧萎缩,却无法在产品上采取任何行动。一定程度上Netscape死于自己糟糕的系统质量 —— 在发展时期所欠下的技术债务。在软件行业,这绝不是个案。Netscape的故事告诉我们,忽视长期质量的价值交付最终将无法持续。敏捷软件开发遵循迭代和增量的开发模式,价值得以更快的实现,但如果忽略了质量,这也会意味着更快的积累问题。以下是在迭代交付过程中忽视质量所引发的一些典型问题。

  • 前期迭代留下的烂摊子,始终没能清理,问题越积越多
  • 既有功能越来越多,迭代中的测试工作量越来越大
  • 既有功能总被新的发布破坏
  • 代码越来越复杂,添加一个功能需要的工作量越来越大
  • 客户开始抱怨,不再愿意接受增量交付

可持续的价值交付才能给组织带来长期的效益,为实现价值交付的可持续,“内建质量”是敏捷软件开发的必然选择,它体现在两个方面:

  1. 预防问题的发生

    在敏捷软件开发中,检查和测试的目的是防止问题的发生,而不是发现问题。Mary Poppendieck曾经这样形容测试的作用,她说:“测试人员的作用不是挥舞拍子赶走蚊子,而是装上纱窗”,为此要做到更早和更频繁地测试(test early, test often),自动化是必然的选择。及时和有效的自动化测试是系统的安全屏障,从源头上防止缺陷的注入。对于问题的预防还体现在一些其它的敏捷管理和技术实践中,如 “持续集成”和“结对编程”等。

  2. 不让问题积累

    为了不积累问题,每一个迭代的交付都要达到特定的质量标准,质量标准同时包含用户可见的外部质量,和系统的内部质量。外部质量,如是否通过集成测试和性能测试等,直接影响用户的当下体验;内部质量,如不良的代码设计是否被重构,是否包含必要的自动化测试覆盖等,影响系统的可扩展、可维护性以及将来的开发效率。为迭代交付的软件定义明确的质量标准,这在敏捷实践中被称为Definition of Done(DoD)。定义合理的DoD,并确保每个迭代交付的软件都达到DoD的标准,是团队维持迭代交付节奏的前提。

    即使在迭代之内,也应尽早暴露系统中的问题。尚未集成和测试的代码隐藏沟通、设计和实现的问题,应该尽量早的进行集成和测试。通过“持续集成”技术实践的实施,做到每天至少一次或多次的代码集成和验证。如果多个团队共享一个代码库,那么持续集成实践就需要拓展到所有这些团队。

好了,第二次交付观察报告。

从外部(业务视角)看敏捷

- 敏捷软件开发遵循迭代和增量的开发模式,以尽快实现和交付用户价值

- 敏捷软件开发在增量交付过程中内建质量,以保证价值交付的可持续性

- ……

* 一个题外话:后来Firefox基于Netscape 重写的代码起家,势头很不错,说明那次重写技术上是成功的。但又如何,只能印证前面的一点,错过时间窗可能意味着失去全世界。

3. 应时而变 ⇒ 抗拒不可预知的变化,还是打造适应变化的灵活性

在“The Agile Samurai”一书中,作者陈述了软件项目的三个简单事实,并指出接受并正确对待这些事实可以避免软件项目中很多误区。这三个事实是:

  1. 不可能在项目开始的时候收集到所有的需求
  2. 不管你收集到什么样的需求,它一定会发生变化
  3. 要做的功能,一定会超过时间和金钱允许的范围

每一次软件开发都是对未知领域的探索,无法预知一切。问题是,面对不可预知的变化,组织应采取什么样的策略,是“抗拒不可预知的变化”还是“打造适应变化的灵活性”?传统软件工程的思路更接近于前者 —— 在项目开始时去预测用户的需求,然后冻结需求,制定相应的开发计划,再按照计划执行,这一过程被称为“预测性的过程”;敏捷软件开发通过不断的反馈和调整,动态地达成目标,这一过程被称为“自适应过程”。

图5 传统的预测性软件过程和敏捷自适应过程比较

图(五)从概念上比较了传统的预测性过程和敏捷的自适应过程。不管你如何预测和计划,最后的实际目标总会发生变化,执行过程也会出现偏差,面对软件开发这样复杂的活动,预测性过程很难奏效。相对应的,敏捷的自适应过程强调反馈和调整,在开发过程中不断修正方向和行动计划,在复杂的市场环境和技术环境中把握和实现业务目标,打造适应变化的灵活性,与价值的交付速度一样,它们都是应对激励竞争和复杂多变的业务环境的核心竞争力。

敏捷软件开发过程承认软件开发的复杂性,致力于构建更加灵活应变的软件开发过程。在迭代开发模型的基础上,每一个迭代完成时,团队更加深入的理解了产品及其构建技术,用户也更加清楚自己的需求。团队根据这些新获取的知识和获取的用户反馈,调整产品方向、需求定义以及技术路线,这些调整将直接体现在接下来的迭代的开发活动中。通过这一过程,团队能够更准确的把握用户需求,适应技术和市场环境的变化。

观察报告的第三次交付。

从外部(业务视角)看敏捷

- 敏捷软件开发遵循迭代和增量的开发模式,以尽快实现和交付用户价值

- 敏捷软件开发在增量交付过程中内建质量,以保证价值交付的可持续性

- 敏捷软件开发在开发过程中不断反馈和调整,以获得适应市场及技术环境变化的灵活性

- ……

4. 与熊共舞 ⇒ 面对风险,需要的不仅仅是勇气;积极和系统性的应对风险

“与熊共舞”来自关于项目风险管理的同名著作,“熊”指的是项目中的风险。“风险与收益共存,通过掌控风险获取相对竞争对手的优势”,这是“与熊共舞”背后的含义。拒绝风险,会使组织丧失竞争优势;承担风险,但在操作上忽略它,同样会把项目带向失败。

风险来自复杂系统开发的不确定性,敏捷软件开发接受并应对不确定性,自然也必须面对风险。掌控风险体现在敏捷软件开发的方方面面,可以说在某种程度上敏捷开发过程就是风险掌控的过程。以下是敏捷开发过程中应对各类风险的策略。

  1. 业务风险

    开发错误的产品是最关键的项目风险。通过敏捷软件开发方法,更早和更频繁的交付产品,获取反馈,及时调整产品开发方向,极大地降低了开发错误产品的可能。更紧密地与用户协作,现场客户参与开发过程,定期向用户演示产品等实践都有助于对产品的方向作出及时的修正。

    不确定性并不意味着范围的无限蔓延,敏捷软件开发包容不确定性,同时为不确定性的设置边界。例如在典型的敏捷方法Scrum中,通过产品待办事项(Product Backlog)管理需求,产品负责人(Product Owner)对产品待办事项最终负责;根据业务价值设定需求的优先级,并依照优先级的次序实现和交付需求;需求的变更只在迭代之间发生,在一个迭代之内,一般不增加或变更需求;需求的变更,必须以符合业务目标为前提。通过这些边界的设定,团队可以更加有序的掌控不确定性。

  2. 技术风险 

    在开发过程中,尽可能早的验证和暴露问题,是应对技术风险的最有效手段。

    • 架构的可行性会给项目带来极大风险,在考虑客户价值的同时,尽量在前几个迭代中安排对架构影响比较大的用户需求,以此来尽早地移除架构风险。对一些不确定的技术点,也可以采取类似的策略。
    • 很多技术问题往往在集成时才能暴露。持续集成的技术实践,让团队在第一时间集成代码、自动构建和验证软件版本,始终保持一个符合质量标准的可用版本。通过持续集成,使过去在项目后期才能暴露的风险得以尽早的被发现和修正。
    • 每个迭代都要交付用户可用的需求,可以尽早的暴露团队在能力方面的不足。

    技术上的风险永远存在,它甚至可能会使项目根本不可行。敏捷软件开发容忍失败,但通过不断的反馈,敏捷开发可以做到尽早失败(fail fast),一方面造成的浪费比较有限,另一方还有时间寻找替代方案或实施弥补措施,在这一次的失败中孕育下一次的成功,这也是业务和技术创新的重要源泉。

  3. 执行风险

    对于软件开发这样复杂的活动,估计和计划的偏差在所难免,它会带来项目执行和交付的问题。敏捷软件开发并不否认计划的重要,但在实践上提倡分层次和滚动式的计划。

计划是基于对未来的预测,根据离现在的时间长短,未来的可预测程度是不同的,基于它们的计划也应该有所区别。

图6 可预测性和时间关系

  • 近期的将来是可以预测的。
  • 稍远的将来可以预测但并不确定
  • 远期的将来则很难预测

相应的,敏捷计划也是分层次的, InfoQ的另一篇文章,《敏捷项目的多层面规划》,把敏捷计划的层次分为为:产品愿景、产品路线图、发布计划、迭代计划和每日承诺,并总结了每一个层次的规划包含怎样的详细程度,越是针对近期的计划包含越多的细节,而远期的计划则更是方向性和总体性的。

敏捷开发的计划并不是一次性完成,随着开发进度的推进,团队会逐步细化接下来的工作计划,如在迭代开始前,对任务做具体规划。这种计划方式被称为滚动式的计划,它降低的计划不能适应最新情况的风险,同时减少了不合理计划对执行形成的负面约束。

计划执行的度量和跟踪同样会影响风险的发现和管理,传统上基于任务完成百分比的度量方式,会隐藏计划执行的潜在风险。比如一个项目的进度是100%设计完成,加80%编码完成,与原计划相符。但实际又如何呢?设计可能不合理,代码质量可能未达到要求,到了集成和测试阶段突然出现进度的巨大落后。在敏捷软件开发中把可工作的软件作为进度度量的基本指标,在团队遵循明确的迭代完成标准的前提下,这样的进度度量是更实际和可靠的,进度和交付的潜在风险得以尽早暴露。

另一方面,在迭代交付模式下,如果项目在限期内不能交付所有的用户需求,但至少可以交付已经完成的高优先级需求,而不是“要么全有,要么全无”,降低了风险发生时所造成的影响。

总之:接受和掌控软件开发的不确定性是敏捷开发的重要基础,也是敏捷软件开发应对风险的出发点。风险管理体现在敏捷软件开发的各个环节和方面,敏捷软件开发中的风险管理是积极的和系统性的。承担而不是躲避风险,并由此提升竞争能力,是其积极性的体现;风险应对与开发过程有机集合,而不是仅依靠单独的风险管理实践进行风险管理,是其系统性的体现。

至此,我们可以提交从外部(业务视角)看敏捷的完整的观察报告了。

从外部(业务视角)看敏捷

- 敏捷软件开发遵循迭代和增量的开发模式,以尽快实现和交付用户价值

- 敏捷软件开发在增量交付过程中内建质量,以保证价值交付的可持续性

- 敏捷软件开发在开发过程中不断反馈和调整,以获得适应市场及技术环境变化的灵活性

- 敏捷软件开发系统性的和积极的应对风险,以通过掌控不确定性获取竞争优势

对以上四点可以总结为一句话:

可持续的快速交付,和稳健的灵活性。

  • 可持续来源于内建质量
  • 快速交付来源于迭代和增量的开发模式
  • 稳健来源于对风险积极和系统的掌控
  • 灵活性来源于不断反馈和调整的开发过程

“可持续的快速交付,稳健的灵活性”,要做到并不容易,它需要开发模式、团队组织和技术的变革,这也是我们在本文的后面的部分要带大家去观察的。

[1] PMI(项目管理协会)旗下的项目管理认证(PMP)在项目管理领域影响巨大,PMP所引用的方法学多为偏重量级的管理方法。2009年初PMI的CEO在他的博客On the Threshold of Agility中表现出对敏捷开发方法和敏捷项目管理极大关注。2011年初PMI宣布将在2011年第4季度推出PMI敏捷认证,详见http://www.pmi.org/Agile.aspx

[2] SEI(软件工程协会)是CMMI的主要开发者,相对敏捷开发方法,CMMI一直被认为是传统软件工程的代表,关于CMMI与敏捷是否冲突在社区中也多有争论。2010年10月发布的CMMI V1.3中增加了敏捷相关的内容,比较突出的是为相关的KPA(关键过程域)增加了使用敏捷方法时的应用指导。

由外而内看敏捷软件开发(上)——从业务视角看敏捷相关推荐

  1. 读《Scrum敏捷软件开发》笔记

    读<Scrum敏捷软件开发>笔记 目录 读<Scrum敏捷软件开发>笔记 第I部分 启动 第II部分 个体 第iii部分 团队 第四部分 组织 第四部门 下一站 第I部分 启动 ...

  2. 敏捷软件开发实践——估算与计划(01)

    目录 一.计划的目的 1.为什么要进行估算和计划 2.优秀的计划是什么 3.敏捷计划是什么 4.小结 二.计划失败的原因 1.基于活动而不是基于特性进行计划 1.1.活动不会提前完成 1.2.延误沿着 ...

  3. 多元化时代敏捷软件开发的崛起与传统软件工程的延续

      多元化时代敏捷软件开发的崛起与传统软件工程的延续 1.传统软件开发模式 1.1瀑布模型 1.1.1概念 瀑布模型,顾名思义,软件开发的过程如同瀑布飞流一般,自上而下,逐级下落.瀑布模型的核心思想是 ...

  4. 【历史上的今天】2 月 13 日:.Net 诞生;晶体管之父出生;《敏捷软件开发宣言》诞生

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2023 年 2 月 13 日,在 2001 年的今天,跨国科技公司谷歌(Google)进行了其历史上的第一次收购 ...

  5. 敏捷软件开发和精益看板管理

    引自 blog.sina.com.cn/s/blog_493a84550100ax35.html 最近看了InfoQ上关于精益看板在软件开发上的一些实践和应用的文章,敏捷软件开发借鉴了很多TPS精益生 ...

  6. 【历史上的今天】2 月 13 日:晶体管之父出生;.Net 面世 20 周年;《敏捷软件开发宣言》诞生

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 2 月 13 日,在 2001 年的今天,跨国科技公司谷歌(Google)进行了其历史上的第一次收购 ...

  7. 《软件工程》第3章敏捷软件开发

    敏捷方法都具有以下共同的特性 1.规格说明.设计和实现过程交织在一起: 2.系统按照一系列增量进行开发: 3.使用广泛的工具来支持开发过程. §3.1敏捷方法 敏捷方法的原则 原则 描述 客户参与 客 ...

  8. 敏捷软件开发:原则、模式与实践——第14章 使用UML

    第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...

  9. 敏捷软件开发的12个原则

    作为一个软件工程师,软件设计和开发是最重要的技能,但是,从整个产品的角度上讲,项目管理能力比开发能力更重要,本文摘自Robert大叔的<敏捷软件开发>,粗体是Robert大叔的话,细体是我 ...

  10. 敏捷软件开发实践——估算与计划02

    目录 一.使用故事点估算大小 1.故事点是相对的 2.速度 3.小结 二.使用理想人天进行估算 1.理想时间和软件开发 2.以理想人天作为对大小的度量 3.给出一个而不是多个估算值 4.小结 三.估算 ...

最新文章

  1. 无人驾驶矿山赛道单笔最大融资:踏歌智行完成2亿元B轮融资
  2. css行高line-height的用法
  3. 因为应用程序的并行配置不正确 sxstrace
  4. 微信小程序函数调用监控
  5. 2020年通信网络基础期末复习
  6. 电脑温度检测软件哪个好_实时检测Mac电脑的温度
  7. mysql 删除过期日志_【转】对mysql日志进行操作的总结包括 启用,过期自动删除 等...
  8. TCGA三个在线可视化网站
  9. java中特殊流程控制语句,深入分析JAVA流程控制语句
  10. 2016 Multi-University Training Contests
  11. Atitit.软件开发提升稳定性总结
  12. mapgis矢量化怎么打分数_MapGIS67操作手册(3-12)MapGIS67矢量化的基本流程
  13. auto CAD 常用快捷键指令
  14. Java语言实现word转PDF(10分钟解决)
  15. 小甲鱼(鱼C)课后作业代码 39讲
  16. JS addEventListener()方法
  17. python创建目录(文件夹)
  18. Hibernate对象状态
  19. mysql case when用法
  20. html防微信抢红包,如何实现仿微信抢红包

热门文章

  1. Lumen开发:lumen源码解读之初始化(5)——注册(register)与启动(boot)
  2. 【leetcode】617. Merge Two Binary Trees
  3. 使用CALayer设置图像边框
  4. 常用邮箱SMTP/POP3地址及端口
  5. python datetime处理时间
  6. 软件项目经理新手上路(11) - 找不到自己,看不见别人
  7. 基于角色的用户权限设计的问题,大家探讨下
  8. redis 在 php 中的应用(Set篇)
  9. iOS平台基于ffmpeg的视频直播技术揭秘
  10. 专访雷水果国:离1.5K至18K 一个程序猿5每年的成长之路