敏捷软件开发揭秘
前言
本篇文章将对敏捷软件开发的方法论及其应用做基本介绍,将描述团队是如何通过协作来完成共同目标的。本篇文章不仅仅适合软件开发人员阅读,同时也适合于团队负责人、项目经理、产品经理、开发经理、测试人员、QA经理、QA工程师、技术文档专员、用户体验设计师等任何涉及软件交付的人员。文章重点介绍技术团队是如何通力协作来计划、构建和交付软件的。但文中没有具体代码的编写,也没有对特定技术的介绍,并且也不会介绍任何微软技术。希望这篇文章可以帮助你改善专业性和团队的效率。
背景
Winston Royce 瀑布模型
引自 1970 年的 IEEE 论文 "Managing the Development of Large Software Systems"
该论文中阐述了,在计算机程序设计开发过程中,无论软件的规模和复杂度如何,都会经过两个必不可少的阶段:软件分析和编码。而许多其他额外的开发步骤,虽然也是需要的,但却都没有像软件分析与编码一样对最终产品作出最直接的贡献,反而增加的开发过程的支出。
然后,Royce 介绍了需要额外的将 5 个重要的步骤添加到整个开发流程中,用于最大化地消除软件开发中的风险:
步骤1:程序设计优先
一个软件程序的初步设计阶段,将被插入到软件需求和软件分析阶段之间。程序设计人员将在此阶段开始进行软件整体的初步设计,包括设计、定义和指定数据处理模型,定义系统间的接口,描述输入输出过程,定义初步的操作步骤等。同时,开始起草易于理解和信息丰富的概述文档,并在后续的过程中始终保持更新。
步骤2:设计文档化
软件开发过程管理的第一个准则就是强制对软件开发过程进行文档化,每一个开发阶段都需要形成必要的文档。
步骤3:过程执行两次
保证软件成功的第二个最重的准则是所开发的软件产品是否是完全的从零开始。通常第一次开发的计算机程序会存在问题,而最终交付至客户进行部署的版本,实际上已经是软件的第二个版本。
步骤4:计划、控制和监控软件测试
在这个阶段中,成本与进度的控制风险最高。因为软件测试过程发生在整个项目进度的后期时刻,如果发生问题的话,备份的方案在此时的可用性最差。
步骤5:让客户参与
采用正式的方式让客户参与到项目中,是软件过程中非常重要的一点,这样就可以在最终交付时间点前进行承诺。
在仔细的阅读 Royce 的论文之后发现:
- 每个阶段被迭代地传递至下一阶段
- 在软件发布之前,整个过程需要被执行两次
- Royce 明确的认为,如果这个过程仅执行一次,项目将会失败
并且不幸的是,从对软件过程结果的描述中可以看出,程序设计这个阶段并没有被限制在顺序的迭代步骤中。
这些都是什么东西?
答案是:
敏捷开发本身并不是一个独立的方法论,其涵盖并描述了多个敏捷方法论。在 2001 年签署的敏捷宣言中,所包含的方法论包括:Scrum、XP、Crystal、FDD 和 DSDM。其后,软件精益实践也呈现出了非常大的价值,并被包含在敏捷开发的方法论中。
进一步阅读 “Agile Principles and Values, by Jeff Sutherland”
敏捷宣言的签署者
敏捷软件开发宣言
我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:
- 个体和互动 高于 流程和工具
- 工作的软件 高于 详尽的文档
- 客户合作 高于 合同谈判
- 响应变化 高于 遵循计划
也就是说,尽管右项有其价值,我们更重视左项的价值。
敏捷宣言遵循的 12 条原则
- 我们最重要的目标,是通过持续不断地及早交付有价值的软件使客户满意。
- 欣然面对需求变化,即使在开发后期也一样。为了客户的竞争优势,敏捷过程掌控变化。
- 经常地交付可工作的软件,相隔几星期或一两个月,倾向于采取较短的周期。
- 业务人员和开发人员必须相互合作,项目中的每一天都不例外。
- 激发个体的斗志,以他们为核心搭建项目。提供所需的环境和支援,辅以信任,从而达成目标。
- 不论团队内外,传递信息效果最好效率也最高的方式是面对面的交谈。
- 可工作的软件是进度的首要度量标准。
- 敏捷过程倡导可持续开发。责任人、开发人员和用户要能够共同维持其步调稳定延续。
- 坚持不懈地追求技术卓越和良好设计,敏捷能力由此增强。
- 以简洁为本,它是极力减少不必要工作量的艺术。
- 最好的架构、需求和设计出自自组织团队。
- 团队定期地反思如何能提高成效,并依此调整自身的举止表现。
由于缺乏实践指导,许多开发人员都经历过噩梦一样的项目。而缺乏有效的指导,会导致项目的不可预测性、错误的重复和工作量的浪费。客户会因为进度的失控、预算的增长和低劣的质量而感到失望。而开发人员会因为在经历长时间的努力后仍然产出了低质量的软件而沮丧。
DSDM
DSDM(Dynamic Software Development Method)通过提供一个框架,考虑在整个软件开发周期内填补一些快速应用开发(RAD:Rapid Application Development)方法的空白。DSDM 方法的主要功能有:
- 用户必须持续参与
- 迭代式和增量式开发
- 提高产品交付频率
- 在每个阶段均进行集成测试
- 满足业务需求是接受产品交付的主要依据
FDD
FDD(Feature Driven Development)是一种方法论的包装。它允许你在较高的层次应用一种方法来管理项目,并同时允许应用其他方法在较低的层次进行管理。FDD 主要关注要能够估计工作量和进度,项目可以作为一个整体级别上汇报状态,也可在非常细粒度的级别进行汇报。但其不会指明应用某个特定的方法来创建进度,而使其能由实施者来决定。这个概念就在于实施者需要观察项目的状态,确认项目的状态如何,是否在进度范围内,是否有偏差等。
Lean
精益思想提供了一种系统级的最优化方法,主要关注于减少浪费和改善系统整体流程的价值。精益在制造业有着丰富的历史,并在近些年流行于软件开发圈子中。
精益源自精益制造理论,其为实现质量、提升速度、客户满足等提供了一整套原则。在精益软件开发中有 7 个原则:
- 消除浪费
- 内建质量于流程
- 增强学习
- 延迟承诺
- 快速交付
- 尊重和权力下放
- 整体优化
将这些原则应用于软件产品交付并不是最终目标。不是说“我们要精益”,而是通过使用精益原则来指导决策的制定和通过选择技术来改进系统的整体。例如,通过 TDD(Test-Driven Development)的实践,在软件的构建初期即检测其完整性,从而支持了在构建的过程中保证完整性的精益原则。
Plan
在计划驱动的开发过程中,如果项目按照计划来进行,则说明项目是顺利的。所以在软件开发中,其依赖于需求的稳定性,也就是明确的和确定的需求。你可能会说,需求能稳定简直太奢侈了,基本上绝大多数的软件项目都做不到。
在计划驱动的方法中,如果在设计阶段更改需求,则成本较低。而如果在整个构建过程启动后再来适应需求的变更,代价将非常昂贵。所以,大部分的精力都投入在了计划阶段。而软件开发确实与此不同,因为无法保证一定能有一个好的设计来使构建的过程可预测。
"Walking on water and developing software from a specification are easy if both are frozen." - Edward V. Berard
敏捷方法正是在尝试打破对需求稳定性的依赖,给出一个过程来适应变化。其通过适应性的计划和演进性的设计来达成。
适应性的计划,意味着变更贯穿整个项目周期,重新计划和重新适应的过程非常频繁。
演进性的设计,可以通过实施自测试代码、持续集成、重构和简化设计等方式来达成。
所以,一种是价值驱动的(敏捷驱动开发),而另一种是计划驱动的(计划驱动开发)。这不是说计划驱动的方法没有任何价值,而是说在敏捷驱动开发中,我们使价值更显示地体现,并经常进行讨论。
敏捷驱动和计划驱动两种方法均依赖于环境状况,这也是它们的短处。而如果环境状况问题没有被跟踪,有可能导致项目失败。这其中的挑战就是如何平衡两种方法,进而取长补短。
Plan 与 Agile
计划驱动开发与敏捷驱动开发之间最根本的差异有两点。第一点是,在计划驱动的模型中,在项目的晚期交付软件产品的一个增量。但是在敏捷驱动模型中,每次仅交付一个较小的增量,而交付的频率非常高。第二个区别是,顺序性与并行性。在计划驱动开发中,在一个过程成功地结束后,下一个过程才能开始。而在敏捷驱动开发中,由于计划的过程一直在进行,所以活动是并行的。
“Plan your work, then work your Plan” by Martin Fowler and Neal Ford
- 两种方法均提供过程、工具和技术
- 两种方法均是严谨的软件开发方法
- 每一种方法都有优势和劣势
- 敏捷方法可以适应多种环境状况,而计划驱动的方法并不擅长
- 敏捷方法仍然是一种严谨的软件开发方法,但是其着重强调了过程中的不同方面
- 计划驱动的方法更强调正式的沟通和控制
- 敏捷方法强调持续的沟通,并有能力适应变化和不确定性
- 通过高度的迭代来达成质量需求要优于通过多种质量控制门限
- 检测工作是否正在被完成要优于当产品完成时检测
- 从满足客户需要的一个目标开始要优于从预测将要交付什么产品开始
能在计划驱动的方法中工作的很好的管理团队,将同样能胜任敏捷驱动的方法。
而如果管理团队在计划驱动的方法中就缺乏能力,在敏捷方法中也一样。
Agile
敏捷软件开发的原则和价值观是,形成一种方法来帮助团队打破传统过程周期的膨胀,而更多的关注如何通过简单的技术达成目标。
那么,目标到底是什么呢?
好,每个软件开发人员和开发团队最主要的目标就是,为雇主和客户交付尽可能高的价值。项目的失败就是未能交付价值。
敏捷开发的关键技术点在于,其将传统瀑布模型中的 5 个步骤压缩进了一个一周的循环周期中。其通过在迭代的周期中,不断的交付较小的软件增量来开发软件系统。并且其允许开发人员在开发过程中进行软件测试和软件评审。快速、低成本和灵活性,就是敏捷的精髓。
"Adoption rates among IT departments are accelerating," says Phil Murphy, vice president and research director at Forrester in a 2011 report.
有很多种敏捷过程:Scrum、Crystal、BDD(Behavior-Driven Development), TDD(Test-Driven Development), FDD(Feature-Driven Development), ADP(Adaptive Software Development), XP(Extreme Programming)等等。尽管如此,众多成功的敏捷团队通过在这些过程中不断的调整,已经演进出其特有的敏捷性方式。而这些改变中最常见的就是将 Scrum 和 XP 结合到一起,使用 Scrum 来管理多个团队,每个团队分别进行 XP 实践。
极限编程(XP)
As developers we need to remember that XP is not the only game in town.- Pete McBreen
极限编程着重强调团队合作,包括管理人员、客户和开发人员。它通过 5 中基本途径来改进软件项目:沟通、简单、反馈、勇气、尊重。
根据维基百科上的定义: “Extreme Programming (XP) is a software development methodology which is intended to improve software quality and responsiveness to changing customer requirements. As a type of agile software development, it advocates frequent "releases" in short development cycles, which is intended to improve productivity and introduce checkpoints where new customer requirements can be adopted.”
极限编程将一套简单具体的实践融合进敏捷开发过程中。极限编程也是一种开发软件的常用方法。非常多的项目团队已采纳这种方式。并且其中的许多团队已通过添加和修改过程实践来适应过程。
- 极限编程是绝大多数敏捷方法论的祖先。
- 20世纪初期,Kent Beck 创造了极限编程理论。
- 融合过程与实践。
Kent Beck 的基本思想是:
- 观察高效团队的实践
- 推动团队将能力发挥至极致
那么,到底 “推动团队将能力发挥至极致” 是什么意思?是下面这张图中描述的意思吗?
或者
都不是,这些描述的都不是极限编程。让我们来看看极限编程意味着什么。
极限编程包含了一组符合敏捷价值观和原则的实践。极限编程是一种独立的方法,而敏捷代表一类方法。所以有很多种敏捷方法,而极限编程只是其中一个。
虽然是这样说,但没有任何其他一种方法能像极限编程一样有良好的定义和作用范围。例如,Scrum 方法大致相当于极限编程中计划游戏实践的部分,只是引入了整体团队的概念。虽然细节上有所不同,但公平的说,Scrum 是极限编程的一个子集。实际上,很多 Scrum 团队通过在过程中增加一些极限编程的实践来扩种整体过程,例如验收测试、结对编程、持续集成,尤其是测试驱动开发。
在所有敏捷方法中,极限编程是唯一一个方法为开发人员的日常工作提供了深入而严谨的规范。在这些规范中,测试驱动开发是最具革命性的。下面图中是一些较好的极限编程实践。
Scrum
Scrum 是一种迭代式和增量式的敏捷软件开发框架,用于管理软件项目、产品或应用的开发。其重点在于“它是一种灵活的、整体的产品开发策略,开发团队作为一个工作单元整体来达成共同的目标”,这与传统的“顺序性的开发方法”是截然不同的。
- 在 1986 年,Hirotaka Takeuchi 和 Ikujiro Nonaka 首次定义 Scrum 为 “一种灵活的、整体的产品开发策略”
- 在 1995 年,Jeff Sutherland 和 Ken Schwaber 联合发表了描述 Scrum 方法论的论文。Scrum 概念首次公布于世。
Scrum 中的角色
在一个产品的形成过程中,有三种核心的角色:
- 产品负责人(Product Owner)
- 开发团队(Development Team)
- Scrum 教练(Scrum Master)
产品负责人
- 产品负责人代表着产品干系人,代表着客户的声音。
- 负责确保产品价值符合业务需求。
- 负责编写以客户为中心的用户故事,并设定优先级,并添加到产品订单(Product Backlog)中。
- Scrum 团队必须拥有一个产品负责人,产品负责人也可以是开发团队中的一员。
- 产品负责人与敏捷教练最好不是同一个人。
开发团队
- 负责在每个冲刺(Sprint)结束时提供潜在的可交付的产品增量。
- 一个跨职能的小团队,人数 3-9 人,进行具体工作(包括分析、设计、开发、测试、技术沟通、文档等)。
- 自组织模式,尽管团队有可能与项目管理部门直接接触。
Scrum 教练
- 负责帮助团队移除障碍,确保团队能够实现冲刺目标。
- 并非团队领导者,但是一个负责屏蔽外界对团队的干扰的角色。
- 确保 Scrum 过程按照其初衷使用。
- 规则的实施者,团队的保护者,使团队始终聚焦在具体任务上。
- 从多个视角上定义,还常被定义为仆人领袖。
- 与项目经理的区别在于,项目经理可能需要进行人员管理。
- 除此之外,不包含任何额外的职责。
Backlog
产品订单(Product Backlog)是为一个产品维护的需求排序列表。它由产品特性、产品缺陷、非功能性需求等等构成。同时包括为成功交付可工作的软件所需要做的任何事情。在 Scrum 中,并不需要在项目初期为所有需求制定冗长的文档。产品订单对于 Sprint 几乎总是足够的。并且,随着产品的不断增长和与客户不断的沟通,产品订单总是在变化。
冲刺订单(Sprint Backlog)是包含了开发团队在下一个冲刺中所有工作的列表。团队需要从产品订单中的故事或特性选择出来冲刺订单,知道团队感觉订单中的工作在这个冲刺中已经足够了。开发团队通过提问“我们能完成这个吗?”的方式将故事或特性添加至冲刺订单中。
概念上讲,团队需要从最高优先级的产品订单开始工作,然后选择关联的低优先级或高优先级的项。但在具体实践中,很难看到团队会去逐项选择,例如,最高优先级的5项,与较低优先级的2项直接关联。
敏捷软件开发调查
这项调查是在2012年8月9日至11月1日之间进行的,由 VersionOne 公司赞助。通过多种多样的软件开发社区渠道,有 4,048 名人员参与了投票。数据由 Analysis.Net Research 公司进行分析并将其编写成一份报告。
谁了解敏捷?
敏捷失败的原因
采用敏捷的壁垒
采用敏捷最常见的困扰
结论
一个优秀的敏捷团队会挑选适合他们的管理和技术实践。在尝试敏捷实践时,常常有众多敏捷无法工作的借口。那些真正懂得敏捷方法优势的人可能已经取得了成功。而那些一直在寻找失败原因的人,或者真的找到了症结,要么完全放弃了努力,要么直接停止了实践。Elisabeth Hendrickson 称这种敏捷为“假敏捷”。
为了支持这个结论,我找到了一句名言:
"In preparing for battle I have always found that plans are useless, but planning is indispensable." - General Dwight David Eisenhower
当然,最好不要总沉迷于任何给定的方法,因为公司和项目的需求和条件都在定期的发生变更,所以想要项目获得成功,我们需要灵活地选择项目管理的方法。没有某种特定的方法永远都是良方,所以这其中的技巧就是要确定哪些方法能满足我们的工作,并不断的加以调整以满足个性化的需求。这才是"敏捷"的根本。
参考资料
- Manifesto for Agile Software Development
- Agile Principles, Patterns, and Practices in C# Robert C. Martin, Micah Martin
- Agile Alliance
- msdn.microsoft.com
- Martin Fowler
- pluralsight
本文翻译自 CodeProject 网站 Monjurul Habib 的文章 "Agile software development methodologies and how to apply them."