UML软件工程组织

 

 

透视迭代开发
 
作者:jayliu 出处:blogjava
 

引子:我们为什么需要迭代开发?

 我们都知道,人对于世界的认识是一项主观活动,它受到各种因素的影响,使得我们不能够一下子对所要认知的事物有一个清晰的了解。具体到软件开发中来,我们会发现,你很难在开发之前弄清楚客户所有的需求。一方面,客户对自己想要什么可能并没有一个明确的想法,这就好比在买衣服的时候,我们在专卖店里看到一个衣服,会觉得自己穿起来很帅,但是你仍然需要把它真实的穿在身上才能看到实际效果,而在你看到这件衣服之前,你能够仅仅凭着想象在脑海里刻画出这件衣服的样子么?

其次,软件工业中我们讲究的是投入和产出比,软件业的成本主要是人力资源的成本。这也是软件项目对时间特别敏感的原因。时间比计划延长一个月,对于一个数十人的团队来说就意味着几十万的成本增加。但是又有谁能够保证自己所做的软件是完美无缺的呢?于是很多时候我们必须对已经开发的部分进行修正,而修正就需要时间。 传统的开发方式下,很多软件项目都是在匆忙交付后发现用户不满意,于是继续修正,再次引发用户的不满意,再次修正,在这样反复地拖延中,客户和软件开发商都筋疲力尽。

我们需要迭代开发,是因为我们深知对事物的认知就是一个探索的过程,软件开发也是一样。在温博格《探索需求---设计前的质量》一书中提到:

美国第34任总统艾森豪威尔上将曾经说过,"计划本身什么都不是,而编制计划的过程就是一切"。我们认同这样的说法,并把它推广到需求过程:产品什么都不是,而开发的过程就是一切。

 或用另一种方式表达:发现什么都不是,而发现过程(探索过程)就是一切。

软件项目本身的意义就在于和用户一起探索他们真正需要的东西并且帮助他们实现。而这种探索,如同在第一段中我们阐述的那样,需要不断的反复,如果我们没有做好迭代和反复的准备,而是希望一次性的把所有工作都做完并且还做得非常好,结果可能恰恰相反。

我们需要迭代开发,是因为我们追求软件质量的最大化。没有人可以制造出完美无缺的东西,但是我们可以通过不断的检查和反馈,使得那些不适合的东西在早期被暴露出来,迭代给予了我们这样一种检查合反馈的机制,让我们不必在事情结束的时候才惊奇的发现我们所一直努力在做的东西其实是一堆废物。

 实践:正确实施迭代开发

 事实上在业界,迭代开发的观念早已经深入人心,然而有多少团队在正确地实施着迭代方法呢?有多少团队通过迭代得到了他们想要的东西呢?很多人简单的把迭代理解为开发的分阶段进行。我们常常看到有项目经理们这样说:我们打算通过4次迭代完成软件的开发,第一次迭代,完成需求分析和软件设计,第二次迭代,完成多少多少模块的开发,第三次,完成其他多少模块的开发,第四次,配置,部署,上线,测试,修正软件bug。虽然我们言必称“迭代”,但是这样的迭代和过去传统的瀑布型开发有多少区别?我们又能够从这样的伪迭代中得到什么好处呢?

在本文以下部分将对迭代开发实践中几个关键方面进行阐述,这几个方面我们概括为以下关键词:变化,周期,目标,反馈,合作。

 变化
 迭代思想带给我们最重要的一个启示,就是要适应变化,要积极、主动地拥抱变化而不是拒绝变化。

 在过去的开发中,我们常常会拒绝变化,以需求分析工作为例,有些项目组在需求分析完成后会要求用户签字,等到交付时,如果客户有什么意见,他们就会拿出那份客户已经签字画押的文件来理直气壮地说:这是你们签字过的东西,我们做的难道不是和这里所说的一样么?

 是的,开发出来的可能是和需求定义文件的内容一样的,但问题是:这份需求定义文件上描述的内容是不是真正能够帮客户实现自己的价值呢?难道我们进行软件开发的目的就是让客户在一份他们根本不清楚有什么意义的文件上签字,然后用这个来反驳用户的真正需求么?我们在软件立项之前总是会告诉用户,这个即将开发的软件会帮助他们如何如何。我们有什么理由为我们做不到这一点而理直气壮地责备客户呢?客户亲笔签名的需求文档难道不是我们整理出来并且讲解给他们听的么?

 如果一个软件项目的目标是帮助客户实现某一方面的增值,但是这种增值的目的并没有达到,我们就可以认为这个软件项目是失败的。即使软件厂商通过这个项目达到了盈利的目的,满腹牢骚的客户也会把自己的意见传播出去。而如果软件厂商认为这种事情是天经地义的话,那么它在以后的软件项目中也很难帮助自己的客户实现他们想要的价值。

 我们必须让自己具有适应变化的能力。因为这种变化是客户需要的,因为这种变化能够让软件更能体现出自己的价值。我并不是说应该无条件地接受这种变化,但是我们可以在事前就这些问题和客户进行充分的讨论和沟通,让他们明白,世界总是变化的,需求本身可能会变化,而这种变化需要人力和物力的支持。让客户也能够适应自身的变化,这是非常重要的。

 软件开发中的每个人都应该对变化有着充分的准备。从事软件业的人大都充满了自信,系统分析师会认为自己可以把所有的需求搞清楚,设计和开发人员会觉得他们做出来的东西完美地实现了需求。所以,如果我们对一个开发人员说:某某,你过去做的这个模块不能用了,我们现在需要重新做起,通常我们会得到积极或者消极地抵制。

 应该让人们认识到:变化并不是对过去工作的否定,而是着眼于未来,使工作更加完善的必要手段。无论是需求,设计还是程序代码,你不可能一次性就把它们做到完美,而只能通过不断的修正,让它趋近于完美。这个过程就是所谓的“重构”。

 有些团队为了保持开发的稳定性,会 “冻结需求”。所谓的冻结,也就是说在一段时间内要客户方代表承诺不对已经开发中的需求进行变动。如果你打算做这件事情,首先必须意识到,需求本身就是需求,它是不会因为一个承诺就真正地“冻结”了。如果目前的需求定义并不能反映用户真正的愿景,在冻结的周期过去以后我们仍然需要对已经做完的工作进行修改。当然,如果需求变化太频繁,在某些时候有必要对需求进行冻结以便让开发更加平稳,同时也给软件开发者和客户一个反思的时间。但如果是需求分析工作方法有误,那就有必要作一些检讨了。

 要适应变化,我们需要让客户和开发团队有心理上的准备,从而能够以认真的态度来对待它。还需要有正确的方法来应对变化,比如对变化的成本估算,效果的跟踪,如何快速有效的对各种变化进行反映等,这是我们必须注意的问题。

周期
 很多人简单的把迭代理解为开发的分阶段进行。有些项目经理会这样说:我们打算通过4次迭代完成软件的开发,第一次迭代,完成需求分析和软件设计,第二次迭代,完成多少多少模块的开发,第三次,完成其他多少模块的开发,第四次,配置,部署,上线,测试,修正软件bug。在这里,虽然他们言必称“迭代”,但是这样的迭代和过去传统的瀑布型开发有多少区别?

迭代开发是要分周期分阶段地进行,但是不能认为简单地把开发周期划分为几个不同的阶段就是迭代。
很多人对于迭代周期有一些误解,比如:

  • 认为迭代只适用于开发阶段,而需求分析和设计工作则不在此范围内。
  • 认为迭代周期可以拉得很长,比如两个月,三个月,甚至一个季度,半年。
  • 将需求分析,设计,开发,测试,部署,用户反馈,修改当作完整的迭代周期,并要求在前一阶段工作完全(或者大部分)完成以后再进行下一步工作(迭代)。

在一个迭代周期内,我们可以做什么事情呢?可以说:所有的事情。如果你认为迭代需要在需求分析完成之后才能开始,或者系统集成必须在所有迭代完成之后才可以进行,你会获得一个真正的瀑布流程开发。

 一个迭代周期意味着对一些特定功能(用例)的探索。“探索”一词可能随情况不同而有不同的含义。对于抽象级别较高,模糊程度比较高的用例,我们需要通过和用户的讨论将它逐渐分解为更加清楚和清晰的用例。对于目前我们认为已经得到了详细定义的需求,需要选取合适的部分进行设计和实现,通过这些部分的实现,对需求定义和技术可行性进行反馈。对那些在上次迭代中已经开发完的模块,应该尽可能快速地让用户提出他们的意见,以便了解是否真正解决了用户面临的问题,以及还有没有可以改进的方面,再根据这些意见安排下一阶段的工作。

 我们是否可以在开发进行之前把需求或者设计全部弄清楚呢?我认为很难。因为通常来讲,用户对于自己的需求只有一个模糊的概念。让我们假设一个饮食业的例子,有一天餐厅经理把你叫入办公室说:马上设计一个新的菜谱,这个菜谱是为某某特定人群定制的,你要让这些人感觉色香味俱全。不过在你把配料和烹调方法都设计出来之前,我们不打算让大厨来具体做这道菜,我们不允许失败,所以你的设计一定要一次成功,你可以用调查问卷,用户面谈等方法获取最终用户的需求,但是记住:你不能去做这道菜。

 这样的事情你可能会觉得很滑稽,但是在软件业,类似的事情人们却认为是天经地义的。

迭代允许我们将开发本身也作为需求探索的一部分,通过用户对已经实现功能的反馈我们和用户都会逐渐明白什么样的软件是我们最终想要开发的。所以,不要等到所有(或者大部分)的分析完了才开始开发,而是尽早对已经捕获到的需求进行细化,尽早开发,以获得反馈。

 在安排迭代计划时,应该指明,这次迭代的目标是什么,在结束时应达到的里程碑是什么。如果有任务提前达到了这个里程碑,我们可以提前结束迭代,或者顺便在剩下的时间内安排其他的任务,但是要注意这种安排的合理性,不要因为这个而使得迭代周期被延长。

 在一次迭代到达所设定的结束日期时,就必须审视各项任务是否达到了里程碑的要求,如果有任务没有达到,原因是什么,我们是否需要对需求和技术方案做出调整。对于没有达到里程碑要求的任务,我们可以采取的办法有两种:

  • 将剩余的工作列入下一次迭代计划中去,
  • 将本次迭代的结束时间向后延迟,等待任务的完成

前一种办法适合于有很大工作量没有完成的情况,这可能也同时说明计划的制定有问题,在制定下次迭代计划时应该考虑对任务完成时间进行调整。后一种办法适合剩余工作量不是很大的情况。

 通常来说,一次迭代完成以后应该有一个产品的新版本可用。这也就意味着:将集成和发布分散到每次迭代中去。借助于一些自动化工具(比如ant),我们甚至可以做到每日构建。

 一个迭代周期应该有多长呢?这并没有一个统一的说法,而是应该视目标和可用的资源而定。但是,迭代周期不宜过长,也不宜过短。迭代周期过长的话,会延缓反馈的时间,可能将许多问题隐藏或是堆积了起来。迭代周期过短,会让人身心疲劳,事情难有大的成效。一般来说,迭代周期应该在2-6周之间。如果安排的迭代周期超过了两个月,你可能就必须审视一下迭代计划的合理性了。

 不要认为下一次迭代应该和上次迭代的时间差不多,刻板地把所有迭代规定一个统一的时间是一个很坏的做法。但是你可以把以前迭代周期中的工作效率作为估算下次迭代时间的一个依据。

 目标
 一次迭代必须有明确的目标:我们希望通过这次迭代达到什么目的。在制定目标时,应该同时考虑另外一个问题:如何检查该目标是否已经达成。这就是所谓的“里程碑”。

 迭代计划必须有明确而可行的目标。明确的意思是它应该是可度量的,不能太模糊,因为你很难检查一个模糊的目标是否达成。比如,我们可以说,这次迭代的目标是对xxx方面的需求作进一步细化和评审,完成xxx模块的开发以加入到软件的下一版本中去。这样的目标是明确而且可行的。反过来,如果我们这样说:我们要通过和用户的讨论明确绝大部分愿景,同时要有一个初步的开发。“绝大部分”和“初步”这样的词让人感到困惑:多少是绝大部分呢,在总量尚未明确的前提下,怎么能够知道完成的确是“绝大部分”而不是“一小部分”?“初步的开发”似乎告诉我们这次开发量比较小,但是具体开发哪个部分,或者开发到什么程度,并没有指出一个明确的概念。

 由此产生了一个困惑,软件项目是一个不断探索的过程,我们怎么能够明确地对未来的事情作安排呢?譬如在项目初始调查用户愿景时,为了实现“明确”的目标,是否这样定义任务:完成20%的用户愿景调查?

 很显然,用户愿景总量到底有多少我们并不知道,所以在这次迭代完成以后如果我们问:是否真的完成了20%而不是15%?很难得到答案。

 为了避免出现这种情况,你必须换个角度来看问题,比如我们可以说:对xxx部门和yyy部门的用户做愿景调查。在迭代完成后,可以检查是否这两个部门所有用户的访谈,调查都已经完成,是否这些部门每个人都认为自己表达了全部的意思。

 所以,如果你发现很难对制定的目标进行度量,那么换一个角度来看事情吧,你可能就会找到一个合适的表达方式。如果你从所有的角度都看不到事情是可以度量的,那么这可能意味着这件事情可能还没有到应该去实施的地步,这时你应该把它从迭代计划中去掉。对于这种情况,有人可能会说:那我们这次迭代可做的事情就很少了,如果真是这样,那就进行一次小的迭代吧,可能把这次迭代的工作做完了以后就会有更多的工作可以安排了。

 有些项目经理在日程表上,很详细地写着:第一次迭代,某月某日到某月某日,第二次迭代:某月某日到某月某日,第三次迭代。。。这样的做法是不恰当的。因为它假设了后面几次迭代的任务量,但是实际上,在前面的工作完成之前,你很难对以后的工作得到一个明确地概念。而且在这样的计划上,可能并没有用于测量迭代成果的里程碑,这样的迭代最后很可能会演变成为瀑布式的开发。所以,在一次迭代完成之前,不要对急着去计划下次迭代,特别是不要试图精确定义下次迭代的时间,因为你连下次迭代要做什么都还不清楚。

 为什么目标的可度量性这么重要呢?在团队开发中,很多信息因为人与人的交流不畅而无法得到正确地反馈,这让我们没有办法实时地掌握项目的进展情况,退而求其次,我们必须阶段性地了解这些信息。如果目标难以度量,迭代结束后我们很难明确到底有哪些工作没有完成,也就无法看到事情的问题所在。

 有些团队中会要求每个成员每天对自己的工作进度以百分比的形式做汇报,他们以为通过这样的方式可以确实的掌握事情的进展,但实际上并不行,因为软件开发中存在很多不确定因素,有时候我们认为事情已经完成了一大半,但是可能因为技术或者其他的原因发现这一大半工作方向是错的,这时候就要推倒重来,而且人们在汇报工作量的时候总是会有一些感情的因素在里面,这就使那些看似精确的百分比打了个折扣。

 所以,我们需要更加实际和细致地划分工作,对目标的完成情况进行度量。这也是迭代周期不能太长的一个原因:如果你把大量有前后关联的工作划分入一个迭代周期,在设定的结束到来时,突然发现只完成了一小部分,这时候虽然亡羊补牢仍然可以,但是中间浪费了大量的人力和物力。

 反馈
 一个男人在大街上走着,他并没有发现裤子上的拉链已经松开了,虽然看到这个情况的人有很多,但他们有各种各样的担心,比如不想多管闲事,怕让那个男人难堪,或者干脆就是想看笑话。结果就是这个人继续穿着一条敞开拉链的裤子在大街上行走。

 这件事情至少带给我们两个启示:1,得到反馈是重要的;2,要想得到正确的,有价值的反馈,你需要其他人的配合。

 对于用户需求来说,没有用户及时地反馈,我们就可能把那些不符合需求的开发继续下去,由于软件中各种功能和模块的依赖性,这种不符合最后可能被放大到数倍。越迟得到反馈,问题可能就越大。

 软件开发中一个很重要的概念是“可行性”和“合理性”,无论我们做需求,设计还是开发,集成,测试,都会遇到这两个问题。有些事情的可行性和合理性是我们可以通过事前的分析进行判断的,但是有些问题就必须有一定的实践作为基础。这也是一个反馈的问题。譬如说在某项目中技术架构师决定采取一个技术架构,但是经过一些阶段的开发发现它有一些技术上问题不能实现用户的关键需求,这时候就必须放弃它。

 “反馈”意味着两个意思,对一件事情的调查和根据调查做出决策。

在意识到反馈的重要性之后,你会要求所有的人都对迭代的成果做出反馈。可能存在的问题是,是不是所有的人都意识到了反馈的重要性并且认真地去做了呢?如果客户认为他们只需要对迭代出来的产品“看看而已”,那么你就很难了解他们一些深层次的想法。再比如一次迭代中某些模块开发的进度比较慢,开发人员可能会抱怨技术方案不能满足要求,而实际的原因可能是设计不合理或者根本就是有人没有认真工作。

 中国国家队前主教练米卢曾经说过“态度决定一切”,反馈作为迭代开发中至关重要的一个方面,必须得到足够的重视。
获得反馈的方式和对于反馈信息的分析是另外一个重要的方面。一般来讲,根据软件开发角色的不同,我们非常关注的是两类人的反馈:项目组之外的客户和项目组之内的各种实施人员。

 软件项目一般都会要求客户方安排专门的业务人员进行配合,在迭代开发中,这种配合不只是进行需求的整理和发掘,还包括对已经完成软件版本的评测。在这个过程中应该有需求分析师的配合。

 在每次迭代完成之后,软件项目组应该有一些总结和分析活动。通过这些总结和分析,找到做得好和做得不好的方面。

 在非迭代式的开发中,也有反馈的环节。比如通常在软件交付阶段会有一个试用期让用户提出意见。而软件团队在各种开发中都会有一些总结活动。迭代式开发的独特之处在于尽量早地引入反馈机制;使得反馈机制更加制度化;并且,更加快速和灵活地分析这些反馈,把得到的结论应用到下一阶段的开发中去。

 对于一些机制引起的问题,比如组织结构不合理,角色分配不明确之类。最好有一个明确的问题记录表。在每次迭代完成以后将这些问题记录下来,同时在下次迭代中努力改善它。如果相同的问题连续出现在几次迭代中,可能就说明项目管理出了问题。

 合作
 软件团队中的合作是人们一直都在提倡的。我们在这里提到“合作”的意思并不只包含团队内部的协作,还包括和客户的合作。

 迭代开发需要快速反应,这需要各种不通角色人员的配合。如果人们做事情总是拖拖拉拉,就会延缓软件项目的进度。而且每个人对自己在迭代中应该做什么事情必须很清楚,这需要事前的准备和角色的合理分配。

 迭代需要用户的配合,实际上最好能够有客户方真正的系统使用者参加到迭代过程中来,因为他们是最有发言权的。很多项目中会让项目经理或是系统分析师担当客户代表的角色,这样做有很多弊病。有时出于各种原因客户确实不能到现场配合的,我们也可以通过其他的途径获得客户反馈。比如一个阶段迭代完成以后,可以把相关操作用截屏加文字说明的方式发给客户,让他们对产品有一个直观的印象。

 为了让团队能够有效快速地配合,应该尽可能使用各种自动化工具。比如自动化测试管理工具,以及配置管理,集成以及发布之类的工具。通过对这些工具的有效应用,使得各个成员能够快速获得信息。

 迭代开发要拥抱变化,主动适应变化。要让每个参与者都认识到这一点:不能够固步自封,或者满足于现有的成就,不去思考可改进的地方。从管理者的角度上,必须重视每一个反馈信息。

 迭代开发追求对任务的度量。很多组织会把这种度量和员工的绩效考评联系起来。这种做法可能是合适的,但是如果只是简单衡量工作量或者工作完成速度和质量,有可能会比较片面。毕竟软件开发是一个环环相扣的过程,表面上来看这个环节处理不好,实际上可能是准备工作做得不好,或者其他人的配合不好。

 所以如果在迭代过程中出现了问题,一定要客观地分析,特别是应该挖掘导致这些问题出现的深层次原因。譬如在一次迭代中测试人员发现了一些bug,但是两次迭代过去了,这些bug仍然存在,这就说明对bug的处理不够迅速(当然如果因为某些原因这些事情被故意推迟了的情况不算)。这时就必须分析一下到底是什么原因造成了信息的不通畅。而不能简单地批评相关责任人。

总结
 本文对迭代开发的五个关键(变化,周期,目标,反馈,合作)方面进行了讨论。作为一种方法论,迭代开发的好处在于它使软件团队变得更加灵活。在实施迭代开发的过程中,应注意不能流于形式化,切实做好每个环节的工作,这样才能获得满意的结果。

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号