本文从敏捷方法的定义,提出背景,实施方法等方面对敏捷方法进行描述,并与传统软件工程方法相对比,分析敏捷开发的优劣。通过实际软件开发的案例分析软件生产的价值观,得出敏捷方法在软件开发中的价值。
关键词 :敏捷开发;增量;迭代;用户故事;文档;软件工程;精益生产
第一章 敏捷开发概述
1.1 敏捷开发的定义
从广义上来给敏捷开发下定义,敏捷开发(agile development)是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。简言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
1.2敏捷开发提出的背景
在实践中,开发人员常常埋怨以精确方法工作的方式。大部分技术人员认为,尽管各种新技术非常吸引人,但是在实践中,很少按照正规方法的复杂流程一步一步前进,RUP、ISO9000,……开发人员常常会被浩瀚的文档所淹没,被繁文缛节的过程压垮。
基于对传统软件工程存在的种种弊端,2001年2月,敏捷联盟会议在犹他州的雪鸟城召开。敏捷联盟是17位不同敏捷开发方法的提倡者共同成立的,目的是推进敏捷开发方法的研究和应用,他们并不要求强制使用某种开发方法,而是提出了敏捷开发的几个核心价值和基本原则:
核心价值:
1.个人和交流重于过程和工具
2.正在运行的软件本身重于复杂的文档
3.与客户的沟通和交流重于使用合同约束客户
4.对变化的快速响应重于跟随计划
基本原则:
1.最高目标是通过快速的和经常的发布软件满足客户的需要
2.提交软件的周期为几个星期到几个月
3.产生正确的软件是衡量进度的首要标准
4.主动接受需求的改变而不是拒绝
5.商务人员和开发人员工作在一起
6.个人必须有动力,要创造环境支持他们的要求,信任他们
7.最有效的交流方法是面对面的交流
8.最好的结构,需求和设计来自于自组织的团队(self-organizing
team),允许任何人提出想法和建议
9.持续改进设计和编码
l0.鼓励正常工作,减少长时间加班
l1.保持简单,减少不必要的部分,认识到简单的设计比复杂的设计更难
l2.定期调整过程,获得更高效率
1.3敏捷开发的方法
前面提到的这4个核心价值观会导致高度迭代式的、增量式的软件开发过程,并在每次迭代结束时交付经过编码与测试的软件。接下来几节覆盖了敏捷开发小组的主要工作方式,包括:
1.增量与迭代式开发
2.作为一个整体工作
3.按短迭代周期工作
4.每次迭代交付一些成果
5.关注业务优先级
6.检查与调整
1.3.1增量与迭代式开发
从下图可以直观的看出增量与迭代式开发的含义:
增量开发,意思是每次递增的添加软件功能。每一次增量都会添加更多的软件功能。使用增量法逐渐地增进功能,那么如果开发花费的时间多于预期,就可以将迄今为止已经增量构建的功能发布出去。(在软件开发的实践中往往项目开发花费的时间大于预期。)
增量地释放版本,可以实际地得到已创造的商业价值。因为在人们开始使用构建好的软件之前,软件开发方是不会真正地得到投资回报的。在那之前,预期的商业价值只是一种估计。如果估算软件开发是困难的,那么就尝试估算投资回报率吧。
迭代式开发:在软件开发的早期阶段就想完全、准确的捕获用户的需求几乎是不可能的。实际上,软件开发经常遇到的问题是需求在整个软件开发工程中经常会改变。迭代式开发允许在每次迭代过程中需求可能有变化,通过不断细化来加深对问题的理解。迭代式开发不仅可以降低项目的风险,而且每个迭代过程以可以执行版本结束,可以鼓舞开发人员。
笔者对迭代开发的理解是先构建软件,然后评估它是否能够正常的工作,然后对其作出修改。而且是根据用户需求的不断变化,不停的对其进行修改,不停的校验是否满足客户的需求,通过迭代找到正确的解决方案。
从XP、Crystal、RUP、ClearRoom等方法学中对比,体会迭代设计的精妙之处:每一次的迭代都是在上一次迭代的基础上进行的,迭代将致力于重用、修改、增强目前的架构,以使架构越来越强壮。在软件生命周期的最后,除了得到软件,还得到了一个非常稳定的架构。对于一个软件组织来说,这个架构很有可能就是下一个软件的投入或参考。
1.3.2 敏捷小组作为一个整体工作
项目取得成功的关键在于,所有的项目参与者都把自己看作朝向一个共同目标前进的团队的一员。“扔过去不管”的心理在敏捷开发项目中是没有市场的。分析师不会把需求“扔”给设计师;设计师和架构师不会把设计“扔”给编码人员;编码人员不会把只经过部分测试的代码“扔”给测试人员。一个成功的敏捷开发小组应该具有“我们一起参与其中”的思想。虽然敏捷开发小组是以小组整体进行工作,但是小组中仍然有一些特定的角色。有必要指出和阐明那些在敏捷估计和规划中承担一定任务的角色。
第一个角色是产品所有者(product owner)。产品所有者的主要职责包括:确认小组的所有成员都在追求一个共同的项目前景,确定功能的优先级以便总是在处理最具价值的功能,以及做出决定使得对项目的投入可以产生良好的回报。在商业软件开发中,产品所有者通常是公司的市场部门或者产品管理部门的人员。而在开发内部使用的软件时,产品所有者则可能是用户、用户的上级、分析员,也可能是为项目提供资金的人。
第二个角色是客户(customer)。客户是做出决定为项目提供资金或者购买软件的人。在一个开发内部使用的软件的项目中,客户通常是来自另一个团组或者部门的代表。在这样的项目中,产品所有者和客户的角色常常是重合的。而对一个商业产品来说,客户就是购买这个软件的人。无论是哪种情况,客户都可能是,也可能不是软件的用户(user)。用户当然也是一个主要的角色。
另一个值得注意的角色是开发人员(developer)。这里使用开发人员来概指所有开发软件的人。它包括了程序员、测试人员、数据库工程师、可用性专家、技术文档编写者、架构师、设计师,等等。使用这一定义,即使是产品所有者在很多项目中也可以被看作是开发人员。
最后一个角色是项目经理(project manager)。如Highsmith(2004a)所述,在敏捷开发项目中,项目经理的角色发生了变化。敏捷开发项目经理会更多地关注领导而不是管理。在某些敏捷开发项目中,承担项目经理角色的人也会承担其他的角色,通常是作为开发人员,少数时候也会担任产品所有者。
1.3.3 敏捷小组按短迭代周期工作
在敏捷开发项目中,对开发阶段没有什么重要的分隔—— 没什么先期需求阶段,然后是分析阶段,然后是架构设计阶段,等等。根据您实际选择的或者定义的敏捷开发过程,您可以在项目的最开始设置一个很短的设计、建模或其他阶段。但只要项目真正开始,在每次迭代中都会同时进行所有的工作(分析、设计、编码、测试,等等)。
迭代是受时间框(timebox)限制的,意味着即使放弃一些功能,也必须按时结束迭代。时间框一般很短。大部分敏捷开发小组采用2~4周的迭代,但也有一些小组采用长达3个月的迭代周期仍能维持敏捷性。大多数小组采用相对稳定的迭代周期长度,但是也有一些小组在每次迭代开始的时候选择合适的周期长度。
1.3.4 敏捷小组每次迭代交付一些成果
比选择的特定迭代周期长度更重要的是,开发小组在迭代中把一个以上不精确的需求声明变成经过编码、测试,实际可以交付的软件。当然,大多数小组不会把每次迭代的结果都交付给用户;敏捷开发的目标只是让他们可以交付。这意味着开发小组在每次迭代中都会增加一些小功能,但是增加的每个功能都经过编码、测试,达到了可以发布的质量。
在每次迭代结束的时候让产品达到潜在可交付状态是很重要的。实际上,这并不是说小组必须全部完成发布所需的所有工作,因为他们通常并不会每次迭代都真的发布产品。例如,我曾经参与一个小组的工作,他们需要在发布产品之前对软硬件都进行2个月的MTBF(Mean
Time Between Failure,平均无故障时间)测试。他们不能缩短这2个月的时间,因为这是他们的客户通过合同约定的,而且检查硬件故障也需要这么多时间。这个小组按照4周的迭代周期工作,他们的产品在每次迭代结束的时候除了没有进行这2个月的MTBF测试,都达到了确实可以发布的状态。
由于单次迭代并不总能提供足够的时间来完成足够满足用户或客户需要的新功能,因此我们需要引入更广义的发布(release)概念。一次发布由一次或以上(通常是以上)相互接续,完成一组相关功能的迭代组成。最常见的迭代一般是2~4周,一次发布通常是2~6个月。例如,在一个投资管理系统中,一次发布可能包括所有与买入和卖出共同基金和货币市场基金有关的功能。这需要6次2周的迭代来完成(大约3个月)。第二次发布可能增加了股票和债券交易,需要4次2周的迭代。可以按不同的间隔进行发布。也许需要6个月来完成第一次发布,而接下来的发布则可能在3个月以后,等等。
1.3.5 敏捷小组关注业务优先级
敏捷开发小组从两个方面显示出他们对业务优先级的关注。首先,他们按照产品所有者所制定的顺序交付功能,而产品所有者一般会按照使机构在项目上的投资回报最大化的方式来确定功能的优先级,并将它们组织到产品发布中。要达到这一目的,需要根据开发小组的能力和所需新功能的优先级建立一个发布计划。要让产品所有者在确定功能的优先级时具有最大的灵活性,就必须在编写功能时使它们相互之间的技术依赖性最小化。如果选择一个功能要求先开发另外的3个功能,产品所有者就很难在发布计划中确定功能的优先级。开发小组不太可能达到绝对没有任何依赖的目标;但是,把依赖性控制在最低程度则是相当可行的。
其次,敏捷开发小组关注完成和交付具有用户价值的功能,而不是完成孤立的任务(任务最终组合成具有用户价值的功能)。达到这个目的的最佳方法之一就是采用一种表示软件需求的轻量级技术(Cohn
2004),即用户故事。一个用户故事(user story)是从系统用户或者客户的角度出发对功能的一段简要描述。用户故事的形式很自由,没有什么强制性的语法。但是,按照大致符合这样一个形式来考虑用户故事是比较有益的:“作为〈用户的类型〉,我希望可以〈能力〉以便〈业务价值〉。”以这样的模板作为例子,您可以得到一个用户故事说:“作为购书者,我希望可以根据ISBN找到一本书,以便更快找到正确的书。”
用户故事是轻量级的,因为并不需要一开始就把它们全部收集和记录下来。与写下一篇冗长的需求说明相比,敏捷开发小组发现采用刚好及时的需求分析方法更有效。通常可以通过在记录卡片上写下一个用户故事的简短说明来开始,对较大的或者分布式的小组,则可以把它录入计算机中。不过故事卡片只是个开始,对每个用户故事,开发人员和产品所有者都应根据需要进行交流。这些交流在需要时进行并且应包含所有必需的人。使用基于用户故事的需求分析方法时,仍可能需要编写文档。不过,工作重点在很大程度上从文档编写转移到了口头的交流。
1.3.6 敏捷小组进行检查和调整
任何项目开始的时候所建立的计划都不是对将来会发生些什么事情的保证。事实上,它只是一个当前的猜测。有很多事情可以让这个计划失效——
项目成员的增减、某种技术比预期的效果好或差、用户改变了想法、竞争者可能会迫使我们做出不同的或者更快的反应,等等。对每个这样的变化,敏捷开发小组都把它看作为了更好地反映当前的实际情况而更新计划的机会和需要。
在每次新迭代开始的时候,敏捷开发小组都会结合在上一次迭代中获得的所有新知识作出相应的调整。如果小组认识到一些可能影响到计划的准确性或是价值的内容,他们就会调整计划。小组可能发现他们过高或过低地估计了自己的进展速度,或者发现某项工作比原来以为的更耗费时间,从而影响到计划的准确性。
计划的价值也可能由于产品所有者获得了期望用户或是可能用户的想法而发生改变。也许,基于用户看到以前的迭代交付的软件后产生的反馈,产品所有者认识到用户可能更想具备某类功能,而对另一个功能则没有之前所认为的那么看重。通过在发布中增加更多用户期待的功能而减少一些低价值的功能,可以增加计划的价值。
以上这些并不是说敏捷开发小组对优先级的改变是随兴而为的。在一次迭代到另一次迭代间优先级实际上是相当稳定的。但是,具有在迭代之间改变优先级的机会对使项目投资回报最大化是大有益处的。
1.4敏捷开发中对文档的要求
有些人认为敏捷不需要文档,甚至不支持任何形式的文档化。在CIO杂志上的一个敏捷案例研究中声称,这是一个误解。
回想一下水晶方法是如何处理文档:
水晶方法把开发看作是一系列的协作游戏,而写文档的目标就是只要能帮助团队在下一个游戏中取得胜利就行了。水晶方法的工作产品包括用例、风险列表、迭代计划、核心领域模型,以及记录了一些选择结果的设计注释。水晶方法也为这些产品定义了相应的角色。然而,值得注意的是,这些文档没有模板,描述也可不拘小节,但其目标一定要清晰,那就是满足下次游戏就可以了。我总是将这些思想以下面的方式向我的团队成员表达:通过它们,你只要了解你明天加入这个团队所要知道的内容就行了。
而极限编程是如何对待文档的呢?
与水晶方法相比,XP认为在团队内外,文档都不必太多,并把它看作是需要交付给客户并由客户付费的故事。我觉得这样做的目标就是通过与其它特性集合进行对照评估,来减少多余的文档数量。XP更依赖于开发人员之间的直接交流来传递相关的知识而不是依靠写好的文档,而结对编程使其成为可能:因为通过结对,你就可以和其它人分享对系统的理解,而消灭“死角”,也就很少需要文档来记录这些知识了。另外,代码与测试也被看作是描述软件实现细节的文档,它没有更新不及时的问题……总而言之,就是团队必需的东西或者客户想要的东西。
敏捷宣言指出有价值且可工作的软件胜于详尽的文档。敏捷宣言是一套基本原则和标准,用于检验某个过程是否敏捷,而不是一个具体的方法论。
要理解这个警示,必须记住非敏捷方法论常有文档驱动开发的特征,因为在写代码之前,它需要以大量的文档作为输入。很多情况下,软件开发团队执行相应的过程步骤,只是因为方法论要求他们这样做,尽管它们几乎没有什么价值。结果,很多开发团队完全放弃了这些方法论。敏捷试图避免漫无目标的文档产物,而再次把焦点放在软件开发过程的关键产物上,即代码。不幸的是,很多人没有认识到应该抛弃什么,从而使那种即兴而为式或纸上谈兵式的有限文档成了目标,这些人基本上没有对瀑布式过程(如SSADM)进行完整的实践。
1.5敏捷开发与传统软件工程的区别和联系
那么敏捷开发是全新理论吗?答案莫衷一是。笔者认为,敏捷开发其实借鉴了大量软件工程中的方法。例如迭代与增量开发,这两种在任何一本软件工程教材中都会被提到的方法,在敏捷开发模式中扮演了很重要的角色。
改善,而非创新。敏捷开发可理解为在原有软件开发方法基础上的整合—取其精华,去其糟粕。因此敏捷开发继承了不少原有方法的优势。
1.6敏捷开发带来的好处
对于业务人员或者软件系统的最终用户来说,敏捷开发带来的好处是显而易见的:敏捷开发能使项目团队在更快地获取投资回报的同时,构建出更高质量的系统。团队一旦进行构建,客户就可以了解其情况,而不必在一开始就“一步到位”。固有的短反馈周期能够迅速提供满足客户真正需求的特性。同时敏捷开发也比传统项目管理方法提供了更多的管理变更和风险的可选方案。此外,它们还允许项目团队以组织——客户、用户和其他部门——能够真正看见、评估和使用的方式,展现他们的创造力和解决问题的能力。
1.7敏捷在软件开发实践中的定位
敏捷的核心是什么?敏捷给软件企业(以及软件开发者个人)带来的好处究竟在哪里?这个问题有很多不同的答案。例如“重视个人和交流”,软件开发者喜欢这样的态度,这是毫无疑问的。例如“重视可工作的软件”,它的价值是显而易见的。但在这一切的背后,敏捷的核心是什么?时下流行的观点是:敏捷就是软件行业里的精益(lean)生产,它的核心是消除浪费。ThoughtWorks中国公司的高层在近日接受采访时明确指出了这一点。
首先考虑质量问题。一些软件企业为了降低成本而忽视质量,但质量低下的软件会造成返工的浪费,反而提高成本。相反,在日常工作中投入更多的精力来保证质量,反而能够为企业节约成本。ThoughtWorks中国公司技术总监Michael
Robinson用软件工程的经典理论来分析这个问题:
任何一本软件工程教材都会告诉你:假设在分析阶段找到并解 决一个错误的成本为1,在设计阶段解决同一个错误的成本就变成10,在实现阶段就变成100,在维护阶段就变成1000。敏捷软件开发中的众多实践正是为了避免低质量和返工的浪费。尽管它们一开始看起来似乎有些麻烦,但它们带来的收益是实实在在的。
另一种常见的浪费则是“为将来准备的投资”。例如为了应付将来可能出现的需求变化而提前引入的灵活设计,如果需求没有发生变化,这些灵活设计就会成为浪费:不仅浪费了将它设计出来的成本,而且浪费了继续维护它的成本。制造业为了降低库存成本而创造出“Just
In Time”的生产和决策方法,ThoughtWorks中国公司总经理郭晓认为这些方法同样适用于软件行业:
如何消除预测错误的浪费?避免预测错误的 根本办法就是推迟决策:决策下得越晚,就越不容易因为预测失准而造成浪费。当然也不能晚到错过了时机、耽误了工作才下决策,这就像丰田制造的Just
In Time,决策也要Just In Time。过早的、含有太多预测成分的决策也会造成浪费,其危害丝毫不亚于过晚的决策。
敏捷的、精益的、实用主义的决策往往是符合中庸之道的:它们往往是各种因素、选择权衡之后的结果。敏捷方法极端重视提升客户价值,为了达到这个目标而采取的手段通常都不可能是极端的。
中庸之道常常有效的深层原因是边际效用递减律:对一个方面的东西重视到一定程度以后,再加入更多的重视,收到的边际效用递减;同样的重视度放到另一个方面上,能够收到更大的边际效用。让每一分投入收到最大的回报,尽可能地消除浪费,这是精益的追求。
设计方案的选择说到底应该是一次成本与收益的计算,而不是个人审美取向的衡量——当然,优秀的程序员能够把这种计算变成本能,笔者认为这就是“软件开发的艺术”所在。敏捷方法强调“简单设计”,同样是经过计算的结果。
在面对一个复杂并且灵活的设计时,首先要衡量的不是实现它的收益,而是“现在实现它”与“将来实现它”之间成本的差额。不论一个灵活的设计的收益和成本如何,只要这个差额非常小——等到未来实现它也没有什么额外的困难,就应该毫不犹豫地推迟决策,等到真正需要的时候再引入灵活的设计。感谢现代化的IDEs,很多时候我们讨论的这个成本差额确实非常小,这是敏捷设计通常取简单方案的原因所在。
值得注意的是,随时进行这种成本与收益的计算并不是一件易如反掌的事。计算本身也有成本。这是最佳实践和工具支持存在的意义所在:你可以用较低的成本得到前人积累的知识。
第二章 软件价值观
2.1 什么是成功的软件项目
1.故事一
有两个软件项目(姑且称之为“项目 A”和“项目 B”),它们在开始时的预算都是
50 个人月,时间是 5 个月。
项目 A 在 5 个月后完工,耗费成本 50 人月
项目 B 在 6 个月后完工,耗费成本 70 人月
在软件圈子里摸爬滚打多年的读者们对这个故事一定有自己的判断——而且我可以大致猜出是什么样的判断。不过先别着急,我们还有另一个故事。
2.故事二
有两个软件项目(仍然姑且称之为“项目 A”和“项目 B”),它们在开始时的计划都是交付
200 项功能。
项目 A 在项目结束时一次性交付了最初计划的 200 项功能,但客户发现其中大约
30 项功能没有太大用处,而另外 30 项有用的功能要等到下一个项目才能实现。
项目 B 在第一个月结束时交付了第一个版本,此后每两周交付一个新的版本。在项目进行的过程中,客户进行了一次业务调整,加入了
90 项新的功能,并搁置了 50 项用处不大的功能。最终该项目交付了 240 项功能。
聪明的读者大概注意到了,前后两个故事讲的是同一回事,同样的两个项目。问题是:请问哪个项目是更成功的项目?
这并不容易回答——实际上它没有标准答案。站在很多软件企业的立场上,项目
A 是一个理想的成功项目:按时间、按成本完成预先约定的任务。
而如果换一个角度,站在客户的立场上呢?也许付钱购买软件的客户会有一些不同的想法。项目
B 从开始之后一个月便交付了第一个可工作的版本,从那时起客户就开始使用这个软件的部分功能,并且不断地把自己使用的感受反馈给开发团队。在真实的业务运营过程中,客户甚至发现了一种新的盈利模式,并进行了一次大规模的业务调整,这次调整的结果也直观地体现在软件项目中。虽然项目B的整体交付速率低于项目
A,但它提供的所有功能都是客户真正需要的,它们为客户提供实实在在的价值——更不用说,客户提前好几个月就开始使用这个软件。
实际上,这是一个关于软件价值的讨论。和“成功项目”一样,对于“软件的价值”,不同的人也会有不同的定义。不过作为付钱购买软件的客户,他对于软件价值的定义是一目了然的:他能够从使用软件中创造多少价值,软件能够为他的业务提供多少价值,这就是软件的价值。或者说得更简明一点:软件价值源自使用。
这正是为什么很多客户青睐“项目 B”的原因——这里并不是肯定所有的客户都有同样的观点,稍后笔者会举出反例,但至少支持这一观点的客户不在少数。因为他们处在一个残酷而快速变化的商业环境中:他们的供应商在变化,他们的客户在变化,他们所处的经济环境和政策环境也在变化。这一切的变化迫使他们的业务也要随之变化。今天这个经济全球化的时代是一个“快鱼吃慢鱼”的时代,客户迫切希望新的软件系统为他们带来竞争优势——哪怕这个软件系统尚未完成,只要能够投入使用。最后,客户对于新的软件系统究竟应该是什么样子并没有百分之百的把握,他们的想法往往要在真正使用软件之后才会浮现成型。几方面的因素加在一起,使得这些客户更愿意尽快开始使用软件、提出反馈、并不断完善软件,而不是提出一组需求、然后坐等几个月之后原封不动地拿到这些功能。
3.一个真实的案例
在 ThoughtWorks 的一个项目中,开发者们在项目开始之后一个月内就发布了第一个版本——只有一些简单的数据采集功能。在发布展示会上,发生了这样的对话:
开发者:这是我们的第一个功能。我们从文本文件、Excel 数据表和遗留数据库采集数据,现在我们的数据库中有这些数据……(展示数据库结构)
客户:唔……有意思。要是你能做这样一个查询(写出查询要求),得到的结果可能会有用。
开发者:可是我们的界面上没有地方做这样的查询操作。
客户:啊,我不需要操作界面,只要每天深夜做一次查询,把报表发到我的信箱就可以了。
开发者:这样吗……另一个问题是,这需要花我们几天时间。
客户:不要紧,把别的任务往后放几天好了,我很想看到这份报表。
开发者:那好吧,下周我们就会开始提供这个报表。
猜猜结果怎么样?一周之后客户就开始每天接收这份报表,并根据报表内容做一些分析和决策。仅仅几个月之后,这份报表给客户带来的收益就已经超过了整个项目的投资——这时项目其他部分的开发甚至还没有完成。
想想这个客户会怎么定义一个“成功的软件项目”?也许这个项目超过了预期的时间,也许投入了更多的人力,但这些并不意味着“项目失败”——只是付出更高的成本。关键在于,他投入的这些成本能够带来多大的收益,他的投资回报率是否划算。对于这个客户而言,如果项目能够随时给他提供可用的、能够创造最大价值的软件,能够随时让这种有价值的想法得以实现,这就是一个成功的项目。
这里所说明的就是一种为客户创造最大化价值的软件开发方法。这样的方法有很多种,但它们有一个共同的特点:尽快、尽可能频繁地交付可以工作的软件,让客户尽快开始使用软件,从使用中创造价值、厘清思路、提出反馈。仍然以
ThoughtWorks 的项目为例,这些项目通常在启动开发阶段之后一个月内就会发布第一个版本,随后每一周或每两周发布一个新版本——每个版本都是一个可以工作的软件,每个版本都比前一个版本具有更丰富的功能,并且每个版本都包含客户认为迄今为止最有价值的那些功能。
“开发下一个版本”的过程叫做“迭代”,这些开发方法最大的共同点就是“迭代式开发”——不是一股脑地交付全部功能,而是每次增加一点、渐进地交付最有价值的功能。
2.2软件开发的梦想与真实
回到文章开始处的两个故事。对于很多软件企业而言,项目 A 是一个“理想的”成功项目。那么,是什么让情况变得不那么理想?
答案是一个所有软件开发者耳熟能详的词:需求变更。在真实的项目中,客户通常不会等到最后一天再照单全收整个项目,因为他知道自己的业务正在发生变化。这时需求变更就出现了,伴随着来回的扯皮和讨价还价。更糟的是,大量的需求变更发生在项目晚期——因为直到这时客户才真正看到、使用到这个软件,他的很多想法才真正浮现成型。随着这种“最后一分钟的需求变更”,项目超期、超出预算也就成了家常便饭。能够像项目A这样完工交付的,实在是凤毛麟角的幸运儿。
为了对付需求变更这个噩梦,软件开发者们还发明了另一个词:变更控制。这个有趣的词暗示着:需求变更是一种“不好”的东西,是需要“控制”的东西。然而站在客户的角度上想想,他在亲身使用了软件之后提出的要求,难道不是最有价值的东西吗?把这种真正创造业务价值的要求“控制”起来,难道是合理的吗?
在前面提到过,并非所有的客户都一定青睐迭代式开发。那么,哪些软件项目不一定需要迭代式开发呢?从整篇文章的内容不难看出,如果客户的业务绝对不会变化,如果客户的需求巨细靡遗非常明确,如果客户不需要尽快开始使用软件以便收回成本,那么迭代式开发对他的帮助就会小得多。不过,如果读者认真思考的话,这样的例子也许并不多——也许比你最初认为的要少得多。一个很好的例子是“神州六号”火箭使用的计算机控制系统。还有多少这样的例子?读者不妨试着自己想想。
为了让迭代式开发能够成为现实,为了确保尽快、尽可能频繁地交付,为了确保每次交付的都是最有价值的功能,软件开发者、软件企业和客户——需要很多的改变。这里既有职责与权利的划分,也有开发过程和团队的重组,还有技术层面的实践指导。这些正是敏捷方法学所涵盖的内容。缺少了这些东西,“为客户创造最大价值”就只能成为一句空话。
第三章 实现敏捷在软件行业中的应用
3.1敏捷方法和企业架构和谐共舞
一份来自Cutter Consortium的报告向我们提出了这样一个问题:“敏捷方法和企业架构兼容吗?”并且也给出了这样一个答案:“是的,但需要付出努力”。该报告的作者推荐运用特殊技巧以允许敏捷方法和企业架构互相受益。此外,他们的观察结果、分析和建议也直接是适用于敏捷方法和“面向服务的架构SOA”之间的结合。
企业架构(EA)和敏捷方法(AM)拥有共同的目标——交付能够跟业务需要对齐的软件,并响应对这些业务需要无可避免的变更。然而,EA和AM在达成这个目标时却采用了截然不同的方式。在报告中,对EA和AM定义如下:
EA处理如下的企业级问题:
通过提供一个整体的业务过程蓝图将业务策略连接到IT系统,蓝图可以映射到架构模式、核心服务和应用兼容性等方面。
通过维护一个当前的数据模式(schemas)、过程流和服务定义等内容的详细目录来改进贯穿于整个企业的一致性
通过减少系统间的冗余以及标识可以统一的组件和系统来改进操作效率
确保灵活的IT能力,能够响应技术厂商以及新的或者增强性的业务流程自动化的变化
通过维护IT 组合(portfolio)、当前和目标架构以及迁移路线图来支持项目成本化和优先级划分
为正在进行中的操作和系统开发提供一个稳定的、可信赖的基础设施平台和公用服务
敏捷方法关注于以下观念:
改进效率:关注于近期的问题,仅开发能够满足当前需要的的部分,允许以后形成设计
改进项目可见的可管理性:关注于允许任务的完成能被有效评估的短期的、迭代的开发周期
通过提供一个完整的过程,关注于广泛的自动化测试、尽可能早并且经常解决集成问题、允许多个(缺少丰富经验的)开发人员在共同的代码上开展工作以及从最终用户处得到持续反馈等方式来改进质量。
通过建立在持续重构过程上的集成来改进(内部质量的)可维护性
改进处理变更的能力:它是一个需求变更、一个澄清、一个新的需要优先处理的特性?通过综合客户反馈计划迭代内容。
通过隐式知识的使用、共享的团队空间以及关注问题的小的组成部分来改进交流效果。
我们会先从EA的视角来检验AM然后反过来检验以分析EA和AM之间的鸿沟。
从EA的视角来看:
敏捷迭代提出的使用一到六个周的时间盒来构建一个可运行的部分系统的要求,很少得到采纳。当在一个迭代发生时尝试EA时,常常会割裂时间盒——在这个周期结束时并没有得到可工作的软件。
在一个典型的敏捷项目中,当系统的设计激增时,采用演进的设计、有机的增量的方式风险很大,可能会导致冗余和不同应用间的不兼容性。EA组希望引领设计和推荐的公用基础设施组件、数据库模式定义等。
敏捷非常依赖于可执行的的工件,例如:编写好的测试(不管是单元测试还是系统测试)。EA的工件不是可以测试的。它们限制了项目的影响范围,因为他们没有反馈环——当没有遵照设计时,不会给出警告。
敏捷提倡的客户作为团队成员是不能被承认的。EA组中不会存在任何一个客户,但是它有一个从IT到运营到开发团队到最终用户的间接的大型的广泛客户群。
从AM的视角看,EA也不是非常有意义的:
EA关注于对齐IT系统和业务策略。一个映射了从现在到将来系统的计划被开发出来,然后落到一个独立的项目中。使用了AM的团队可能会使用此类文档中的信息,但当这些文档到达团队时它们已经失去了上下文环境,会变得难以理解。而且,文档是可测试的。不能接触现实状况,这也是EA团队被视作“象牙塔”架构的一个主要原因。
为了减少冗余并增进一致性,EA组会针对如何构建应用而产出参考架构、推荐框架、发布指南。AM团队将这些决定看做是单个项目的领域,不会由未在”前线“上的人来口述。
EA也关注于企业内不同应用的集成。同样,EA组推荐使用参考架构和框架的特定方案。许多的AM团队任务这些决定的是不成熟的甚至是毫无根据的。
最后,EA方法通过考虑了将来的设计(例如建立抽象来轻松应变)的方式来应对变更。AM团队将此方式视为是不成熟的,认为是典型的庞大的预先设计(BDUF)。实践AM的团队宁愿迟些使用抽象,通过重构并依赖于自动化测试来允许变更。
报告的标题确实说:“是的,但需要付出努力”,所以仍然还有希望。但需要EA组和AM项目认识到对方有价值的贡献,并在他们的工作中做出适应性调整。EA组和AM团队可以相互得到以下收益:
一个AM团队应该认识到虽然参考架构和框架可能是一个项目级别的BDUF,但在企业中需要重复做,而且耗费好多。如果已经建立好了就没有理由再发明轮子了。
EA团队应该保证信息在正确的范围内以正确的方式可提供。例如,创建的工件应该努力与每个项目创建的工件相关。
EA组应该考虑将客户和他们的指南视为是一类需求。
每个AM项目的架构应该与架构组进行联络
努力将AM项目范围内的重构变成是企业级的。
应该建立可测试的EA工具
1)标准的基础设施和平台配置
2)数据模式
3)服务
4)参考架构
5)业务流程模型
EA应该确保企业级的“上下文”应该是随时间流逝而分段的,以解决AM团队关于BDUF的质疑。
EA应该与项目的生命周期有关。
信息流应该是双向通道,当AM团队在参考架构或者框架的瑕疵或者不足时,他们需要一种执行变更的方式,这个变更也应该有方式返回到EA组。例如,EA的过程应该支持企业服务的增强。
AM团队可以尽可能去影响企业架构
企业内的测试环境应该增进一致性、重用并启用集成。AM团队是编写测试的专家,他们应该进行均衡。EA工件应该尽可能变得可执行。
InfoQ同报告的两位作者(Michael Rosen和Jim Watson)就该专题的内容以及导致他们给出的推荐方案的客户经验等方面进行了交谈。Jim
Watson描述了最场景的场景:
一个曾经使用过其中一种但因为缺乏对另一个的使用而失败了的项目会最大程度拥有使用两者的经验。例如,一个重要的文档处理系统可以使用最好的AM实践开发出来,但不能协调好系统的EA需要如跨越需求、接口、和操作性问题等。作为选择,一个采用瀑布方式的项目会准备妥当它的所有的企业架构,但是却不能向及早的向客户展现它的价值,或者不能够通过有意义的迭代来解决风险问题。所以,这些paper都是来自于经验的,例如:项目是如何因为忽略了其他可行的规程才陷入这种境地的,有效的处理方式是什么等。
一个意义更加深远的案例可能是在项目启动时均衡EA和AM。 然而,这其实非常难,很少发生,主要是因为组织性问题,以及谁在过程的哪个部分被涉及的角度。你会看到很多的失败,例如架构师跟客户(更惨的是在根本没有客户)但没有开发团队参与的情况下整理需求,然后开发团队脱离开架构师进行接管。
Jim Watson和Michael Rosen告诉我们,关于这个专题的范围,SOA可以被看作是EA的一个实例。因此这里所有相关的问题和解决方案适用于采用了SOA并存在AM团队的组织(无需惊讶,这与InfoQ上的文章SOA和敏捷:是朋友?还是敌人?相吻合)
EA和AM的交互并不依赖于SOA,但值得注意的是SOA提供了相互的兴趣和问题以允许进程一起使用EA和AM。例如,想在一个SOA主导的项目定义真正有用的业务级别的服务可能具有难度,一个缺乏AM开发实践的由EA主导的SOA会产生许多的SOA
shelfware,因为它很难实现或者仅仅定义出不是真正需要的接口。
一个推荐的方案是, 对一个AM团队而言它被当作架构的一个包含部分,作为每个团队的成员与EA组进行联络。当被要求阐明推荐Architect
Reloadus 或是 Architect Oryzus(其定义见Martin Fowler的Who Needs
an Architect? )中的哪种架构类型时,Michael Rosen建议哪种也不采用。在大的组织中会拥有重要的EA组,一个典型的IT组可能拥有2000个员工,500个架构性的重大项目,在EA组中只有70个架构师。没有足够的架构时可供应因此Architect
Oryzus很难应用。Architect Reloadus同样不能得到应用,因为它们没有可实施的环境。有效的架构师的使用方式是作为一个单独的AM团队的咨询顾问,这样,一个来自EA组的架构师就可以发挥效用而不是嵌入到团队中。
所以,拥有EA组和AM团队的组织不必要互相容忍,虽然他们拥有共同的目标,他们的缺省操作模式是不与其它成对的并且(成对使用通常会)产生问题。因此这些实践等对达成企业的战略目标和交付战术性的软件项目非常有用。
3.2走向敏捷三模式
敏捷联盟创始人之一、咨询师兼图书作者Mike Cohn最近根据其自身经验将“如何帮助团队采纳敏捷”总结为三对核心模式,当团队向敏捷过渡时,可以利用这些模式。Mike建议,团队或者组织在逐步采用敏捷的过程中,应该从每对模式中选出一个最适合他们自身情况的模式。
3.2.1范围有多广:“小步前进”还是“全面推广”
“小步前进”是指最初在一个试航团队中尝试敏捷的转型,然后逐渐推广到整个组织中的方法。Mike建议,这种方法在以下几个方面具有优势:最小化因错误而导致的成本、将最初成功的可能性最大化、培养内部的“专家”,以协助后期推广过程的顺利进行。Mike紧接着提及三个隐患:团队在试验阶段产生的早期的成功,可能会给整个组织带来错误的期望;组织推广所用的时间会更长;一旦失败,怀疑者将把其视为公司无法实现承诺的一种信号。
与其相反,“全面推广”的特征是从一开始就让所有团队进行转型,它可以在以下方面让企业受益:展现管理中的各种承诺,组织会变得更加灵活,避免同时使用两个过程带来的不一致,以及减少总体上的抵触感。Mike同时也指出了“全面推进”的缺点:高风险,高开销,可能需要机构重组,会遇到来自于组织的很大压力。
3.2.2如何对待技术:“技术实践优先”还是“迭代优先”
“技术实践优先”要求团队接受敏捷是从关注XP的诸多实践开始的,比如简单设计、测试驱动开发、结对编程、持续集成以及短迭代周期。它带给团队的好处是:转型的启动非常迅速而且平滑。Mike指出这种方法的不足在于:通常较难做到,而且会导致开销激增,同时还可能将团队带离以用户为中心的思考,从而失去了敏捷的真正意义。
相反,“迭代优先”方法,它最初只关注“团队以迭代方式工作”,一旦这个目标受到阻碍,才着手改变技术实践。它的优势可能在于:它很容易实现,而且遇到团队成员抵触的可能性很小。但也有另一个风险:团队可能永远也不会采用对于改善敏捷而言最基础的工程实践。
3.2.3可见性怎样:“秘密行动”还是“公开推广”
“秘密行动”是指团队在采用敏捷实践过程中积累的大量知识只保留在团队的内部。它允许团队在受到其他人关注之前就能获得成功,这就是它给团队带来的好处;那些关注即来自于希望模仿他们的人,也来自于可能会反对他们的人。其缺点包括:难以获得组织所能提供的必要的支持,同时,即使这个团队成功了,也不容易说服怀疑者们去信服。
“公开推广”是指团队在采用敏捷过程中所做的努力对于团队以外甚至组织以外都是公开的知识。它的优势在于:它会激励团队去坚持采用敏捷之路,帮助团队得到外部的支持,更早地发现怀疑者们的疑虑,
并证明高层管理者支持这种变迁并希望它成功。其可能引起的不良后果是,假如公开宣布开始做某件事,最终却没有成功,别人会认为这是非常鲁莽的,也就是说,此时反对者的质疑声就彻底抵消了这种方法的优势所在,而这正是“公开推广”的劣势。
|