不可不读 敏捷经典--《新方法论》(转载至http://www.cnblogs.com/me-sa/archive/2008/01/14/1037910.html)
The New Methodology
作者:Martin Fowler 翻译:坚强2002
源文档 <http://www.martinfowler.com/articles/newMethodology.html>
过去的几年中,敏捷开发蓬勃发展,敏捷方法被当作修正机构结构僵化的一剂良药抑或是打通软件过程奇经八脉的不二法门。本文我将探索敏捷方法的源头,不是强调它何等重要而是要把关注点放在它的适应性和以人为本这两个方面。
Contents
- 无章法 里程碑 敏捷
- 可预见性VS 适应性
o 泾渭分明的设计与实施
o 需求的不可预见性
o 控制不可预见的过程—迭代
o 适应性的客户
- 以人为本
o 人件
o 程序员:重任在肩
o 度量之难
o 业务领导者的角色
- 自适应过程
- 敏捷开发的特点
o 敏捷宣言
o Scrum
o Crystal
相关文献
过去几年中软件过程思想领域最引人注目的变化恐怕就是“敏捷”一词的出现了。我们讨论过敏捷方法在软件开发的应用,如何把敏捷引入开发团队中,也讨论了如何防止那些激进的敏捷主义者对一个良好的开发实践跃跃欲试的“变革”。
这一软件过程领域的新运动得益于二十世纪九十年代软件过程领域各式各样人们的努力,基于自身的愿景,他们要探求软件过程的新道路;这是提出的观点并不新奇,事实上很多人都坚信多数成功的软件都是采用了那些被用过多年的方法。不幸的是由于没有受到足够的重视,特别是没有专业人士的认可,这些观点胎死腹中不了了之。
本文也是那次运动缘起的一部分,最初发表于2000年七月,正如我一贯的行文风格,我写这篇文章试图深刻理解“敏捷”;从1996年起我有幸和Kent Beck, Ron Jeffries, Don Wells以及其他Chrysler C3的团队成员合作,使用极限编程的方法,写文章时已经有了数年的实践经验。
我尝试和有相似观点的人谈话、阅读他们的作品,我觉得只是从极限编程的角度来探讨敏捷是不够的。所以本文我将细数诸多敏捷实践方法的异同。
本文的初版: The New Methodology (Original)
那时我的观点也是我一直的观点就是:一些基本原则构成了这一新方法论,而这些原则与之前已有的原则截然不同;
本文一直是我的网站上最受欢迎的文章之一,这也意味着我有义务不断的更新它的内容。本文的初版探寻了新旧原则间的不同并通过一个敏捷方法的调查来深入的理解它。时过境迁调查中涉及的敏捷开发的内容已经发生了变化,但是新旧差异依然存在,我们将继续讨论下去,回头再说,现在开始…
无章法,繁重,敏捷
多数的软件开发都是一个混乱无序的活动,常常就简单的划分成“CODE&FIX”两个阶段,这就是它的特点。软件的编写没有一个指导性的计划,系统的设计是由一系列短期的决定构成的。当系统规模小的时候这个方法还真的表现不错,但是随着系统规模变大新功能的开发日益艰难。雪上加霜的是这时BUG也无处不在而且难以修改;这种系统的典型特征就是在做到"feature complete" 之后将有一个漫长的测试阶段,这个阶段将把时间计划完全打乱,因为测试和调试的时间难以预计;
解决上述问题,这就是引入软件过程方法论的初衷。方法论将一些严格的过程应用到软件开发活动,目的就是提高软件开发的可预见性和效率;他们是怎么做的呢?他们把其他工程学的原理引入进来强调计划的重要性,通过一个详细的计划来解决问题。因此这时的方法又称计划驱动的方法。
工程方法学存在了很长时间,但是并没有取得显著的成功。它们甚至没有流传开,最为人诟病的是它太官僚主义了。采用该方法要照顾太多的琐碎的事情,这让整个开发节奏慢了下来。
背负着力挽狂澜的期望,“敏捷方法”应时而生。对于大多数人来讲,敏捷方法最大的吸引力就是它能解决工程方法论的官僚主义问题。这个方法论试图给出一个介于“无过程”和“过度过程”之间的折衷方案,使用一个适中的过程来获得合理的收益(成本和收益的一个平衡)。
之所以能做到这一点,是因为敏捷方法与之前工程方法论强调的那些观点有着显著的不同。
最直接的不同点就是它不是文档驱动的,通常对于给定的任务只需要较少的文档就可以了。它倒是有点像是代码驱动的,遵循着一个规则就是把源代码作为文档的一部分。
但我不认为这是敏捷开发的关键,文档的精简只是一个表象,背后有两个深层次的原因:
- 敏捷方法是适应性的,而不是可预见性的;工程方法论尝试用较长的时间把软件开发的绝大部分做到计划里面,在事情没有变化的时候这个方法表现不错。所以本质上它是拒绝变化的,而敏捷方法恰恰是欢迎变化的,它强调在变化中适应和成长.
- 敏捷方法是以人为本的而不强调过程的重要性。工程学方法论是想定义一个放之四海皆准的过程,无论谁用都可以。敏捷方法断言没有什么过程会提高开发团队的技能,过程的角色就是在开发团队的工作中提供支持。
下面的环节我们将从更多的细节来探讨这些不同,这样你就能理解到底什么是适应性、以人为本的过程,它的优势与劣势,以及最关键的一个问题:无论你是一个开发者还是软件用户,敏捷是不是你需要的。
可预见性VS适应性
泾渭分明的设计与实施
软件过程通常引入的方法论原则是源于土木工程学或者机械工程学。而这些原则强调建造之前的计划。工程师会提供一系列的图纸精确的描述要建造什么已经怎么把建造的东西进行组合。许多设计上的决定,比如桥梁负载,在设计图纸的时候就已经确定了。之后图纸移交给另外一个小组甚至是另外一个公司来施工。整个的实施工程是严格按照图纸进行的。实施过程中会遇到一些问题,但多数是无关痛痒的小问题。
由于图纸已经明确说明了各个小块的内容以及怎么组合,它们的功能就像是一个细化的实施方案,它指出要做完成什么任务,以及这些任务之间的依赖关系。这就可以进行进度预计和工程预算。图纸甚至包括人们具体怎么实施工程,这样实施工程的一方不需要太智能,尽管他们往往技术高超。
所以我们这里看到的是两个截然不同的活动。设计很难做出预计,需要大量的有创造性的人参与,而实施是很容易预计的。一旦完成了设计就可以制定实施计划,有了计划我们就可以对实施过程进行预计和控制。在土木工程中,实施比设计和计划的成本消耗时间消耗都要大。
脱胎于上述理论的软件工程学方法论也就变成了这样:我们需要一个可预见的计划,用技能比较低的人就可以完成它。要做到这一点我们就必须把设计和实施分离开,因此一个出现了:我们必须知道怎样做软件设计才能让实施工作在设计之后一马平川的进行下去。
这个计划是什么样的呢?很多时候它的角色就是UML中的设计符号。如果我们可以使用UML来做所有的重要的决定,我们就可以构建出来一个实施计划并把这个计划移交给开发组进行编码。但这个有一个关键问题,你能用设计把编码变成一个可预见的实施活动么?如果可以的话,消耗的成本是在一个可接受的范围内么?
这些引出来一些新问题,首先怎样把UML式的设计转化到程序员可以接受的状态。UML式的设计有一个特点就是纸上看起来很不错,但是到编码实践的时候严重的错误就会凸显出来。
土木工程学的模型都是基于多年工程的实践总结,佐之以强制执行,加之精确的数学分析。而UML式的设计只能依赖同事评审,这样就造成一些错误只有在编码和测试阶段才浮出水面。甚至对于一些高水平的设计人员也会认为把设计变成软件是一件很神奇的事情。
另外一个问题就是平衡支出,建一座桥的设计费用大约是总支出的10%,剩下的实施费用。在软件开发中编码占用的时间远远小于这个比例; McConnell 指出对于一个大型的项目只有15%的时间来做编码和单元测试,这几乎和建桥的比例完全相反的。即使你把测试也作为实施的一部分设计依然保持50%的比例。这就点出了软件开发中的设计与它在其它工程学分支中的角色迥异不同!
这些问题让 Jack Reeves甚至得出这样的结论:事实上源代码就是设计文档而实施阶段就是使用编译器和连接器。当然这时所有的实施阶段就可以完全可以也应该自动化完成。
这种看法可以得出下面的结论:
- 软件开发中: 实施是很便宜的甚至是免费的
- 在软件开发中所有的努力都在设计上,因而需要有创造性和才华的人
- 创造性的过程很难计划,所以可预计性几乎是一个不可能完成的任务
- 我们要意识到软件工程学与传统工程学的区别,这是一个完全不同的活动,需要一不同的过程。
需求的不可预见性
每一个我参加的项目我都会听到这样的小插曲,开发人员告诉我“项目最大的问题就是需求总是变化”,让我感到惊异的是任何人对此都表示不适应;在开发商业软件的过程中,变更是正常的,问题是我们如何面对它。
一种方式是把需求变更的原因归结为糟糕的需求分析。这种观点的隐含意思是需求分析要在编码开始之前对需求有一个全面的理解,然后用户签字,签字之后启动开发过程并尽量不做变更。这里有一个问题那就是充分理解需求是很难的一件事情,而无法对需求的成本进行评估是这件事情更加难上加难。比如你要给你的车添加一个遮阳篷,而销售人员无法告诉你要添加10美元还是100美元。不知道花多少钱你怎么判断是不是要买?
众多因素导致估计很难做到,因素之一是软件开发是一个设计活动难以计划和估计;因素之二:基本资源一直变化难以估计;因素之三:估计取决于过程中的人,人是很难进行预计和量化分析的。
软件是没有物质实体的,在它没有做出来之前你很难看到它的位置。直到你用的时候你才知道那些功能点是有价值的哪些是没有价值的。这就要求人们应该认为软件需求是可以变化的,软件就是应该是“软”的。需求不仅仅是可变,而且是应该变;花费大量精力来跟客户确定需求,特别是客户也曾经涉足软件开发那就更糟了,因为他们知道软件变一下很容易;
即使能得到一个精确的稳定的需求,你依然难逃厄运。今天的经济形势就决定了软件的内容快速变化。今天的好需求,六个月之后就可能一文不值;即使需求不断的改进也是跟不上经济发展的步伐;经济是无法预言的,否定这个观点的人要么是撒谎要么是有足够的实力可以左右市场;软件开发中的其他事情都取决于需求,你得不到一个稳定的需求,你也得不到一个可预见的计划。
可预见性不可能做到吗?
总体上讲,不是的;有些软件开发是可以做到可预见的。像NASA太空穿梭机软件开发就是软件可预见性的样板。这个需要大量环节,大量时间,一个大型的团队,一个稳定的需求。但是我不认为多数的商业软件和太空穿梭机软件属于统一范畴。所以需要有一个不同的开发过程。
存在一个危险就是做不到可预言的时候“做可预言状”;研究方法论的人不善于识别边界条件:
在那个点上方法从合适变成不合适;绝大多数的方法论者都希望自己的理论放之四海皆准,所以他们也不愿意公开这个边界。这就导致了方法论误用的事情,比如把可预见的方法用在了不可预见的环境中。
那样做是很有诱惑性的; 可预见性是令人向往的,当你明明知其不可为而为之的时候,这就会导致人们早早的做了计划,之后局面慢慢失控;你发现计划与现实相去甚远,你可以在一个较长的时间内依然装作计划是有效的;但有时候两者过于不符,就不能视而不见了,失败总是痛苦的。
所以如果你在一个不可预见的环境中就不要使用可预见的方法论。那需要多个项目控制模型,多个客户关系模型,这最终还解决不了问题,真的很残酷。可预见性很美好,但是太难实践了。就像大多数问题一样,最重要的是意识到问题的存在!
不依赖可预见性并不是说你要应付一堆不可控的、混乱的事情。相反你需要一个过程可以应对不可预见性。这就是适应性所关心的。
控制不可预见的过程—迭代
在不可预见的世界里我们如何自处?最重要的也是最难的就是清楚地知道我们的位置!我们需要一个诚实的反馈机制可以频繁的告诉我们当前的位置。
得到这种反馈的方法就是:迭代开发!这不是什么新主意。迭代开发有一大堆相关的关键词:增量开发,渐进式开发,螺旋…. 迭代开发的关键就是不断的有可用的新版本的系统出来,它可以是最终系统的功能子集;这些可用的系统在功能上不完善,但是已经做出来的是满足需求的。在最交付之前需要做细致的集成测试。
这个的意义就在于没有什么比一个测试过,集成的系统更逼近真实的需求;文档可能隐藏缺陷,未测试的代码可能有很多隐患,当时当人们做到电脑前用一下的时候,问题就昭然了:无论是系统Bug还是误解需求问题一下子浮出水面。
迭代式开发对于可以预见的过程同样是有效的。只不过在不可预见的环境中它是必要的,因为这时要应对变化。长期的计划通常是不稳定的,单次迭代的短期计划是稳定的。迭代开发都是基于上次迭代的结果,有一个坚实的基础。
一个问题就是迭代的周期应该多长。不同的人有不同的答案。XP 建议是一到两周。SCRUM 建议一个月左右。Crystal 可能更长一点. 有一个趋势就是每一次迭代尽量的短,这样可以频繁的接受到反馈,明确自己当前的位置。
适应性的客户
适应性的过程需要与客户建立不同以往的关系,特别是开发过程是由单独的一个公司来做的时候。当你雇用一个单独的公司来做开发许多客户会倾向于选择定价合同。告知开发者需求是什么然后投标,接标,开发团队的义务就是把软件开发出来。一个定价的合同需要有一个稳定的需求一个可预见的过程。适应性的过程和不稳定的需求意味着不能进行在常规概念下的定价开发。把定价开发的模型放到适应性过程中,最终会以痛苦的爆发结束。爆发的结果就是开发方和客户两败俱伤。毕竟客户要的是他们业务需要的东西,如果不能满足这个目标那么即使不付给开发方一分钱他们还是受损失了。事实上这时损失比软件做成功要付的钱还要多,因为客户付钱做软件是要用软件赢利的。
这样定价开发在一个非可预计环境中应用对于双方都是有风险的。这意味着客户要做出变化!
不是说你无法进行开发的前期预算,只是说你不能定死时间、价格、范围。常规的敏捷方法是定下来时间和价格,允许范围做可控的变化。
在适应性的过程中客户可以做更多细粒度的控制。每一次迭代都可以做结果检验并纠正开发方向。这就拉近了客户和开发者的关系,真正的合作关系。这种级别的契约并不是适合每一种客户,也不是适合每一个开发团队,重要的是能让适应性的过程顺利的跑起来。
所有这些都会给客户带来很多好处。首先是他们得到了更多关于软件开发情况的信息反馈。一个可用的系统,尽管可能很小,但是可以尽早的投入生产。客户可以根据业务的变化来提出一些变更,同时也可以知道这个软件在真实环境中的运行情况。
这个过程中每一小块功能都可以看出项目进行真实状态。而预见性过程要通过检验和计划是否一致来验证。这样就很难发现开发上是不是已经背离了计划。通常的结果就算是在项目的后期会有一个较明显的脱轨情况。敏捷开发中每一次迭代都有一个持续修正计划的过程。如果坏兆头能早日显露出来,那么我们就还有时间来做出应对。风险控制是迭代开发的关键优势!
敏捷方法通过保持短期迭代,将这一优势更加凸显出来,能够通过各种不同的途径把变更看出来。Mary Poppendieck 在她的文章"A late change in requirements is a competitive advantage".里面帮我总结了各种不同的观点。我相信好多人都已经注意到用户自己在开始的时候都很难描述清楚他们想要什么。我们发现用户都是在判断什么是有用什么是没用的过程中不断的了解到自己的需要。通常最有价值的功能点开始的时候并不是很明显,直到客户开始有机会对软件提出改变。敏捷方法就是要寻求这方面的优势。鼓励客户通过在系统构建的过程中不断搞清自己的需求,通过快速的整合变更来进一步构建新系统。
See Related Article: Is Design Dead?
上述提出的内容都是承担着保证项目成功的重任。通过考察一个可预见的项目的计划就可以判断它是否成功。在既定时间和支出限制先完成的项目是成功的。这种度量方式对于敏捷开发的环境是没有意义的。对于敏捷开发者这些问题直指商业价值—客户从软件中得到的价值比做软件的成本要多。一个好的可预见项目会按计划进行,一个好的敏捷开发项目的会和最初的计划不同并优于最初目标。
以人为本
执行一个适应性过程是不容易的。特别是它要求有一个非常高效的开发团队。团队不仅要求每一个都很强,队伍组合起来的力量也要求很强。这里有一个有趣的协作:不仅是适应性项目需要一个强大的团队,很多优秀的开发者都喜欢适应性的开发过程。
人件
传统方法论中的开发过程中,其中一个目标就是把人作为一个可替换的部分。成功的过程可以把人当作各式各样无差别的资源来对待。你们有分析师,程序员,测试人员,和项目经理。个体不重要,重要的是他的角色。你要做一个项目计划,设计师和测试人员是谁并不重要,重要的是他们的数量是多少。
但这就引出了一个关键问题:软件开发过程中,人是可以随意替换的部分么?而敏捷开发是拒绝这种假设的。当然明确提出人不是资源的是Alistair Cockburn. 他的文章 Characterizing People as Non-Linear, First-Order Components in Software Development,指出可预见过程需要各种组件的行为都是可以预见的。但是人不属于可预见的组件。而进一步的研究结果表明:人是软件开发中的最重要元素。
在他的文章中把人也当作组件,这就是人在过程和方法论中的位置。这种看法的错误就是人是会经常变化的,是非线性的。有着独一无二的成功和失败状态或者说是模式。这些是必须首先考虑的,是不能忽略的。我们可以看到过程或者方法论设计者的失败往往是由于忽略了人的因素。
我们怀疑就这一方面软件开发是不是违反人的本性,当我们用计算机编程的时候我们在控制一个可预见的设备。我们在茫茫人海中找到自己的位置去做一件工作,是因为我们擅长做它。
尽管 Cockburn最明确的表达了软件开发中以人为本的思想,其实这个是很多软件开发思想家的共识。问题在于,多数时候方法论并不没有把人看作是影响项目成功的首要因素。
如果你期望你的开发者是无差别的插件,你就不能把他们看成一个个的个体。这会降低士气和生产力。最合适的人用在最合适的位置,这就是你想要的:人件!
把人放在第一位是一个重大的抉择,需要一系列的决策来辅助推动!把人当作资源在商业领域是根深蒂固的,它源于Frederick Taylor's 科学管理论. 运作一个工厂, Taylorist 方法是有意义的。但是对于高创造性和专业的工作,比如软件开发,这个理论就不合适了,而事实上制造也也逐渐从Taylorist模型中脱离出来。
程序员:重任在肩
Taylorist理论的一个重点就是: 做工作的人不是那些知道怎样能把工作做到最好的人。在工厂里面由于诸多原因这或许是对的。部分原因是多数工人并不是很有才能、有创造性的,还有一个原因是管理者和工人收入差距造成的紧张关系。
最近的历史渐渐告诉我们在软件开发领域这是不对的,越来越多的聪明而能干的人被吸引到这个光华夺目前景光明的领域。 (这也是我离开电子工程学的原因。)尽管经历了世纪初的低迷,软件开发行业依然聚集了大量精英才俊。
(有一个很有意思的换代现象,有些有趣的现象让我好奇在过去十五年是不是越来越多的聪明人进入这一领域。而每一次换代都会有一些代表性的变革.)
你想要雇用或者留住优秀的人,你就必须意识到他们是专业才干,他们是最适合管理自己技术工作的人。Taylorist观念是将计划抽离出来,这种观念起作用除非是计划者比做这件事情的人更精于业务!如果你有聪明主动的人做事情,那么这个理论就不是很有效了。
管理以人为本的过程
以人为本在敏捷过程中有一些特有的表现,这些表现也会导致不同的效果。并不是所有的效果都是一致的。
相比较而言,接受这个过程比应用这个过程更重要。通常软件过程都是管理者要求强制执行的。而多数情况下是推行不利的,特别是管理者有相当长的时间离开开发活动的时候。接受一个过程需要责任委托,这需要全体团队成员的成员。
这样会有一个有趣的结果:只有开发人员自己可以选择一个适应性的过程。特别是极限编程的实践中尤其如此,它需要许多可执行的原则。相比起来Crystal要求的原则比较少,因而受众较多一些。
另一个观点就是开发者能够做所有的技术决策。XP深得要领在其计划过程中只有开发者能估计一个工作所需的时间。
这种技术领导权的分离是管理层的一个重大变革,这样就要求开发者和管理者责任共担,处于相当的位置。注意我说的是相当,管理者依然是管理者,只不过把开发者的专业能力重视起来。
在工业领域这一变化的重要原因是技术在生产中的比重日益增加。过不了几年技术知识就会落伍。技术是工业领域的生命线,很多进入管理层的人会发现他们的技术能力日益萎缩。开发者会意识到他们的技术能力会渐渐消失而必须信赖新一代的开发者。
度量之难
如果在一个过程中,一个人指责另外一个人没有按照合理的方式做一件事情。领导就需要有一些方法进行判断谁对谁错,虽然科学的管理推动了对人们劳动成果进行客观评价,这件事仍然比较困难。
对于软件的度量更是如此,即使你全力以赴,软件开发中一些很小的事情你都难以度量,比如生产力。没有一个好的评判方法怎么进行相关的管理控制呢?就像说不能超标,而标准却晦暗不明。
引入度量管理而没有好的度量方法会带来很多问题。Robert Austin 做过这方面的讨论.他指出要做度量你就要把所有的重要因素都纳入到度量体系之中。任何漏掉的因素都会不可避免的影响度量体系的功用,没有达到预期的效果。度量体系不利是基于度量进行管理的命门所在。
Austin 的结论是必须要在基于度量的管理和开发者自我管理之间做一个选择。前者适合那种重复性的工作场合,不需要太多的知识技能而产出又容易量化—这都是和软件开发背道而驰的。
这一传统方法的核心在于所有的运作都是基于一个假设:基于度量的管理是最有效的管理;而敏捷组织认为这种特征的开发活动往往障碍不断。敏捷主义者认为这时委托式(开发者自我管理)的管理更有效果。
业务领导者的角色
继续上面的话题,技术人员是不可能自己完成过程中所有事情的。他们需要业务需求的向导。这就引出来适应性过程的另外一个重要方面:开发人员要和业务专家紧密合作。
这就超出了多数项目中业务角色的范畴,敏捷团队需要的不是临时沟通而是需要与业务专家持续的沟通。此外这是开发者每天都要面对的,不是管理级别的一个事情。由于开发者在他们的领域内有自己的原则,他们所要做的就是与其他领域的专家协同合作。
上面说的大部分都是适应性过程自身固有的特性。由于适应性过程意味着事情会迅速的发生变化,因而你要不断的和业务专家进行需求确认。
最让开发者恼火的是让他们做无用功。业务专家要保证自己的工作质量来让开发者信赖自己!
自适应过程
我已经讲了很多关于软件项目适应性的话题,如何不断的调整软件来满足客户需求。然而还没有完,还有另外一个角度可以看适应性:过程本身也在不断的变化。一个项目使用的适应性过程和一年前的适应性过程不会相同。开发团队经常做的就是找到以前的一个适用的过程,然后修改一下开始使用。
自适应的第一步就是常规的回顾已有过程。通常每一次迭代都要做这件事情。每一次迭代之后的短会上可以问自己几个问题: (摘自Norm Kerth )
- 我们哪里做好了?What did we do well?
- 我们学到了什么?What have we learned?
- 我们怎样做到更好?What can we do better?
- 什么让我们困惑不解?What puzzles us?
这些问题可以引导你思考如何对下一次的迭代过程进行改进。这样的话问题随着项目进行逐步解决掉,过程与团队之间配合就更加融洽。
如果自适应出现在项目中,在组织形式上会有所体现。一个自适应相关的结论就是不要相信一个方法论就可以一劳永逸的解决问题。每一个团队都应该选择自己的过程,并且随着项目进行不断的协调。其他项目过程的经验作用就是用来吸纳,估计底线,开发者的责任就是根据手头的任务调整过程。
敏捷开发的特点
敏捷是软件开发的原理之一,在这个大的概念之下有很多具体的方法比如: Extreme Programming, Scrum, Lean Development, etc. 每一种具体的的方法都有自己的思想 社区和和领导者;每一个社区各有特色但是都遵循一些共同的基本原则。社区之间也互相学习,很多参与者也都在混迹于不同的社区之间,总而言之,这是一个复杂的生态系统。
其实我已经把我对敏捷的总体理解描绘出来了。现在我要介绍一些其他的敏捷社区,我只能浮光掠影的快速提一下,没有深入挖掘。
既然要给出一些引用,有一个好主意就是把敏捷开发的资源列举一下。非盈利网站 Agile Alliance 一直致力于敏捷开发的研究。看一下Alistair Cockburn 和Jim Highsmith的书。 Craig Larman's 的书里面提到了很多有用的迭代开发的历史。要了解我对敏捷的看法那就关注一下我的articles 和 blog.
下面是一个不完全列表,它只是反应了在过去的十年间敏捷开发的变化发展,里面的方法都对我曾经有巨大的影响。
敏捷宣言
2001年初一群人聚在一起交流敏捷相关的话题,他们在日常的工作中都已经进行了大量的敏捷实践,会议最后发布了一篇《敏捷宣言》Manifesto for Agile Software Development.
在此之前这个工作组就已经提出一些软件开发的观点。多数观点是来自面向对象社区,他们一直主张迭代式开发。2000年从写这篇文章开始就试图把各种过程拢在一起讨论一下。那是这些方法还没有一个通用的名字但是总是被描述为“轻量级”。很多人多这个名字不以为然,认为它没有完全表达出来这些方法的本质。
2000年,这些方法被Kent Beck在俄勒冈的会议上广泛提及。尽管这个工作组主要关注极限编程Extreme Programming (一个最吸引眼球的社区,很多非极限编程的人也参与进来) 。当时一个讨论就是关于XP作为一个泛化的运动或者一个具体的运动,哪一个更好些。
如果没有记错的话,这个工作组是由Jim Highsmith 和 Bob Martin组建的.他们把活跃在社区又有着相同观点的人聚集在一起。初衷是把人们聚在一起能更好的交流各自对方法的理解。Robert Martin 想用一些简单语句把这些技术的共性整合出来,并给它一个名字,就是给那把“伞”一个名字。
在定名“敏捷”的过程中,敏捷宣言的部分内容也相继提出。一些基本的原则在工作组里面最初提出,后来在WIKI上得到后续的补充发展。
提出敏捷宣言的无疑需要极大的勇气,我很惊讶敏捷宣言在内容上的所达到的深度尽管敏捷宣言不是敏捷的严格定义,它还是可以帮助你抓住敏捷的核心思想。敏捷宣言提出之后不久, Jim Highsmith 和我写了一些文章article for SD Magazine 来进行进一步阐述.
去年,敏捷宣言的十七位缔造者的部分成员再聚首.当时提出了一个建议:敏捷宣言的作者们应该领导发起一些敏捷运动。而作者们一致的意见是是那些真正的敏捷实践者创造了敏捷宣言。没有一个小组可以成为整个敏捷社区的领袖。我们帮助船舶靠岸同时也时刻做好准备有人把船开走,最终十七位敏捷宣言的缔造者只是作为敏捷社区的普通成员默默做着贡献。
之后这些作者又组织了“敏捷联盟agile alliance.这是一个非盈利组织目的是进行敏捷方法的推广和研究。每年它都会出资在美国召开年会。
XP (Extreme Programming)
XP—极限编程是二十世纪九十年代年末开始最早流行起来的敏捷方法。XP太有名气,在很多地方你无法绕过它.
XP最早发端于Smalltalk社区, 二十世纪八十年代末开始和Kent Beck 、 Ward Cunningham 紧密合作.他们都在九十年代初期通过众多的项目不断的优化自己的实践。并得出软件开发方法中适应性和以人为本的重要理论成果。
Kent通过一些做项目顾问期间不断调研来发展上述的观点。特别是在 Chrysler C3 project,项目中,这个项目作为极限编程的发源地而声名远播。1997年左右他开始使用极限编程一词。(C3 项目让我和极限编程结缘,也让我和Kent深厚友谊的开始。)
二十世纪晚期极限编程被广泛传播,最初是通过新闻组和Ward Cunningham's wiki, 在那里Kent 和 Ron Jeffries (C3项目的同事) 花费很多时间来解释概念以及跟各种思想做辩论。最后一批书籍在九十年代末出版对极限编程的一些细节进行深入的探讨。这类书籍多数以Kent Beck的 white book 为基础.2004年Kent出版了白皮书的第二版 second edition 重申了极限编程的重要思想。
XP有五种核心价值:沟通 反馈 简化 勇气 尊重 (Communication, Feedback, Simplicity, Courage, and Respect). 这些价值通过十四条原则和二十四个典型实践来解释。观点就是实践是一个开发团队每天都要面对的事情。而五种价值是极限编程能实施的知识基础和沟通基础。五种核心价值是在实践中体现出来,没有实践就无从谈起。没有价值目标的实践是生搬硬套邯郸学步。五种核心价值和实践相辅相成,而这中间有一个巨大的障碍,而敏捷的基本原则就是联系二者的桥梁。许多XP的实践都是实验性的,而最终被人遗忘。随着这一技术的复兴,XP浪潮推动一个又一个的实践以价值为导向互相推动,互相影响。
最让人记忆犹新的,也是最初吸引我的,就是对测试重要性的强调。虽然所有的过程都提到了测试但多数都是没有太重视。而极限编程是把测试作为开发的基础,每一个开发人员一边写代码一边写测试。测试被放在持续集成中这样就为未来的系统打造了一个稳定的平台。XP方法在这里常常被冠之以Test Driven Development (TDD) ,这种思想甚至影响了那些非极限编程的过程。
极限编程方面的出版物有很多,有一个混乱的地方就是白皮书第一版和第二版的变动,上面已经说过了第二本从新的角度重新阐述极限编程。第一版影响深远,当你阅读极限编程的资料时,特别是2005年出版的那些都是以第一版为蓝本。事实上网络上对极限编程的描述多数也是源于第一版。
second edition of the white book的出发点就是发现更多, 第二版用160页的篇幅介绍了极限编程的背景和实践。Kent Beck 在世纪之交为这一系列的书编辑了一个多色版本,如果只能挑选一本的话我选紫色的那本 purple one, 记住第一版是最经典的。
多数资料都是以第一版为基础,只有少数是以第二版为基础例如: The New XP (PDF) by Michele Marchesi ,他是Sardinia敏捷会议的发起者.可以通过 yahoo mailing list进行极限编程的讨论.
早期对XP社区的巨大热情是源于对XP的喜爱。我认为它巨大的影响力是因为它讲一些具体的技术和敏捷的方法的原则嫁接在一起。很多早期的敏捷文献都忽略了这个问题:敏捷真的是可行的么? XP提供了一系列的工具将敏捷的希望成为现实。
Scrum
Scrum 也是八十年代、九十年代期间面向对象技术圈子里面很盛行的一种迭代开发方法。这种方法的佼佼者是Ken Schwaber, Jeff Sutherland, Mike Beedle.
Scrum 关注软件开发的管理,将迭代切分成每30天的迭代 (称作'sprints');通过每天的SCRUM会议实施紧密监控。它没有像XP一样特别强调人与实践的紧密耦合关系,事实上XP的管理也的确与其截然不同。
Ken Schwaber 是支持Scrum的活跃分子,他的网站website 资源丰富,他的书 book 大多是第一手文献。
Crystal
Alistair Cockburn 一直是敏捷社区重要的声音。他设计的软件开发方法水晶体系为不同规模的团队量身打造开发过程。 Crystal之所以被看作体系,是因为不同的方法应用是根据团队规模和关键的变化严重程度决定的。
水晶方法中的变化点都具有一些共性,有三个比较明显的:安全性(是否可以完成项目的目标) ,效率 可用性(开发人员是不是适应)。这些方法也有一些共性比较重要的三个是:频繁移交,反馈改进,紧密沟通。
可用性优先是水晶思想体系的重要部分。 Alistair的目标就是寻求一个可以完成目标的最小过程:应用最少的原则,足够精简的人;结果就是Alistair认为Crystal 比极限编程更关注特定场景下该方法是否适用,尽可能的减少失败。
除了 Crystal原则本身,还没有比较详细的阐述,最著名的文章是Crystal Clear, wiki 上也有进一步讨论Crystal的资料。
Context Driven Testing
从一开始就是软件开发者推动着敏捷社区的发展,而软件开发过程中的其他人也受到这个运动的影响。最明显的是测试人员,他们更倾向于使用瀑布模型的思维方式。通常测试的工作就是验证软件是不是和规格说明书一致,而在敏捷开发中测试人员的角色就没有这么清晰了。
结果是一些测试社区的人开始质疑主流的测试思想。后来组成了一个名叫context-driven testing的小组.关于这个观点最好的诠释是在Lessons Learned in Software Testing .这个社区在网络上也是相当活跃,可以看一下 Brian Marick 的网站(敏捷宣言的提出者之一),还有 Brett Pettichord, James Bach, Cem Kaner.
Lean Development
我还记得数年前敏捷大会上跟一位女士讲敏捷思想和制造业的精益生产运动的情形。Mary Poppendieck (and husband Tom)这位敏捷社区的积极支持者, 主要关注“工作反复问题”,以及精益生产和软件开发如何互相取长补短。
Taiichi Ohno在丰田倡导的精益生产运动常备称作丰田生产体系。精益生产观点被很多早期敏捷主义者接受, Poppendiecks 关于这些观点影响的文章最为著名。工程学上将设计和实施割裂开,因此大体上我对这种类比推论表示担忧,但是精益研究方向还是有一些很有趣的观点的。Poppendiecks的 book and website 是一个很好的切入点.
(Rational) Unified Process
面向对象社区另外一个著名的过程就是Rational Unified Process (sometimes just referred to as the Unified Process). 这种思想是源于UML,认为UML可以统领整个过程。由于 RUP 与敏捷同时出现所以两者是否一致的讨论就一直不断。
RUP是由一系列大规模的实践构成,与其说是过程,不如说是框架。它不是为软件开发提供一个过程,而是摆出一堆通用的过程让你根据自己的项目来选择。所以团队要使用RUP首先要做的就是定义自己的过程,或者用RUP的专业词汇--开发用例。
RUP的要点就是用例驱动(开发是由一个个用户可以看到的功能点驱动的),迭代,架构为核心(较早的进行一个架构设计然后贯穿项目始终)。
我自己的RUP应用经历就是它无穷的变化. 我发现RUP应用的描述已经从严格不变的瀑布式开发过渡到敏捷。RUP在市场上呼声很高,仿佛是无所不能的。
尽管RUP社区卧虎藏龙,我还是推荐一下: Phillippe Kruchten and his book 这是RUP的起点. Craig Larman 也在他关于面向对象的新作里面介绍了RUP的敏捷方式introductory book .
你也要敏捷么?
敏捷并不适合每一个人,要走这条路有些问题必须考虑。我同时又坚信方法论会有广泛的适用性,会被更多的人应用到实践中。
当前的形势是,好多方法论还是停留在Code&Fix阶段。应用一些规则会使混乱状态有所改观,敏捷方法的优势就是比那些重量级的方法使用更少的步骤。轻量级是敏捷的最大优势,简单的过程更容易遵循,过程也总是聊胜于无。
对于敏捷的新手,问题就是从哪里开始。无论是使用新的技术还是新的过程,你都要做出变革。你要看它是不是适用于你的环境,我的建议和对其他新方法的建议一样:想想当时我们是怎么接受面对对象技术的.
第一步是找到合适的项目进行敏捷实践。由于敏捷是以人为本的所以首先你要组建一个愿意进行敏捷开发的团队。不情愿的被拉入开发队伍不仅工作难以顺利进行,而且在敏捷方法中这直接关乎开发成败。.
还有就是你是不是有合适的用户,他也同意使用敏捷的方式与你合作。如果用户不合作,你不可能将适应性过程的优势发挥到极致。说到这里我的确发现有些用户不愿进行敏捷合作,但是当他们理解了敏捷方法之后他们就改变主意了。
有些人声称敏捷方法不适用于大型项目,我们 (ThoughtWorks)就成功的成功的完成了数个敏捷项目,每个项目都在百人左右。尽管如此我还是建议你从一些小项目开始尝试。大项目天生就很难把握,比较适用的就是那些在可控范围内的项目。
有人建议用一些商业影响较小的项目进行实践,即使错了也没有太大的损失。然而一个无关紧要的项目一般测试要求也比较低,大家都不太关心结果怎样。我还是建议大家找个有点风险的项目试一下。
当然最重要的事情就是你能找到一些有敏捷经验的人指导一下。一个尝试新东西难免会犯错,找到那些已经犯过很多错误的前辈你可以少走很多弯路。当你开始接触一门新技术,一位良师益友价值千金。在ThoughtWorks很多朋友都是敏捷开发领域做培训的,所以我们可以自给自足。这也丝毫没有改变我的看法:找一个良师益友。
一旦你找到了,听听他的建议。但是这里会出现一个状况就是:言听计从;我的经验是很多技术没有真正的实践一下很难说已经理解深刻了。 最好的一个例子就是我们的一个客户要用两个月的时间进行极限编程的试验。在那个期间他们完全按照老师说的做,即使他们认为那是一个很糟糕的主意。试验期的最后他们停下来了,他们觉得还是用原来的老路子吧。
一个开放性的问题是敏捷方法的边界在哪里?很多新技术在开始你都难以摸清它们的边界,直到有一天你使用它们的时候失败了。敏捷方法还太年轻,还没有足够的应用来给它划定一个界限。这就像很难判定一个软件开发过程哪些方法是成功哪些是失败的一样,千头万绪,不一而足,难下定论。
这样看你是不是要用敏捷方法呢?我像这会让很多人为难,如果你的团队成员没有紧密合作的强烈要求,那么这件事情就会阻力重重。永远不要在一个拒绝敏捷方法的团队尝试敏捷实践,经验之谈。
过去十年间,敏捷实践一直进行着,在 ThoughtWorks 如果客户同意我们一直使用敏捷方法,大多数的时候他们会同意的。我或者说我们对这种工作方式一直充满兴趣!
本文的重要修正:
13 Dec 05: General overhaul of the paper. Changed list of methodologies to a survey of flavors of agile.
April 2003: Revised several sections. Added section on difficulty of measurement and context driven testing.
June 2002: Updated references
November 2001: Updated some recent references
March 2001: Updated to reflect the appearance of the Agile Alliance
November 2000: Updated section on ASD and added sections on DSDM and RUP
December 2000: Abridged version published in Software Development magazine under the title of "Put Your Process on a Diet"
July 2000: Original Publication on martinfowler.com