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

2011 年 5 月 18 日

敏捷很火,也让人迷惑

敏捷软件开发方法受到越来越多的关注。图(一)是来自 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(关键过程域)增加了使用敏捷方法时的应用指导。


感谢滕振宇对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2011 年 5 月 18 日 00:008116

评论

发布
暂无评论
发现更多内容

架构师训练营第四周作业

邓昀垚

极客大学架构师训练营

手把手教你AspNetCore WebApi:Swagger(Api文档)

AI代笔

ASP.NET Core swagger web api

我把这个贼好用的Excel导出工具开源了!!

冰河

Java Excel 冰河 mykit-excel

洞察:区块链的危机与契机

CECBC区块链专委会

比特币 区块链 数字货币

阿里互联网神话,超级工程双十一如何打造终于开源了(共4篇)

小Q

学习 架构 面试 算法 阿里

Code Review怎么做

胖鱼2号

架构师训练营第 1 期 - 第 4 周 - 学习总结

wgl

叹为观止!GitHub标星过万,腾讯技术官发布的“神仙文档”图解网络,简直是秋招福音

云流

程序员 互联网 网络通信协议 计算机知识

纸质书和书写的慢时代

boshi

随笔杂谈

看了这篇网络编程,就可以和面试官聊聊了

Simon郎

网络编程 websocket Java 分布式

4 个问题图解浏览器垃圾回收的过程

Java架构师迁哥

「国庆」忆读书生涯

我是程序员小贱

美食 旅行

技术与思想:区块链的双重属性

CECBC区块链专委会

区块链 大数据

中小企业如何启动产品科普直播?

boshi

内容 营销 直播 企业应用

手把手教你AspNetCore WebApi:入门

AI代笔

ASP.NET Core web api

架构训练营-week4-作业

于成龙

作业 架构训练营

LeetCode题解:429. N叉树的层序遍历,递归,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

区块链即将涌现更多典型落地应用

CECBC区块链专委会

区块链 落地应用

手把手教你AspNetCore WebApi:增删改查

AI代笔

ASP.NET Core web api EF Core

手把手教你锤面试官01——HashMap面试全攻略

慵懒的土拨鼠

java基础 面试求职

源码分析怎么做?

tison

源码分析

LeetCode题解:102. 二叉树的层序遍历,递归,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

在互联网站上怎么准确分辨别出MG平台真假VX(LGF7998)黑网的验证方法?

InfoQ_6b6a6317a692

区块链更多典型落地应用即将涌现

CECBC区块链专委会

区块链 落地应用

《我想进大厂》之MQ夺命连环11问

艾小仙

kafka MQ 面试题 程序语言 面试求职

makefile从入门到入门

MySQL从删库到跑路

c++ Linux 编译 makefile

中台: 54 天搞定中国百强企业的库存中心建设,而时间还能够再缩短至少一倍

日编一码

spring-boot-route(七)整合jdbcTemplate操作数据库

Java旅途

Java Spring Boot JDBC

架构训练营-week4-学习总结

于成龙

架构 作业 互联网架构 架构训练营

《统计学习基础:数据挖掘、推理和预测》-斯坦福大学人工智能学科专用教材

计算机与AI

第一周-食堂就餐卡系统设计-UML设计

kawayi

由外而内看敏捷软件开发(上)——从业务视角看敏捷-InfoQ