蒋炜航

什么时候适合使用“敏捷开发”呢?我们的经验是需要两点:一、团队有三名或以上的研发工程师;二、团队内有一名合适的Scrum Master。

clip_image002


有道云笔记团队成立于从2010年,从成立伊始我们就一直积极地在实践中尝试Scrum(敏捷开发的一种项目管理方法)的做法。到2012年底,3.0发布时,我们在5个主要平台(PC、iPhone、Android、iPad、Web)上总共发布了46个版本,累计了近千万激活用户。在这个过程中,我们逐渐摸索出一套适合以产品和技术创新为核心的中等规模(数十人)研发团队的Scrum实践经验。

1、Scrum不是万能药,要在时机成熟时推行。

什么时候算时机成熟呢?我们的经验是需要两点:一、团队有三名或以上的研发工程师;二、团队内有一名合适的Scrum Master。

刚开始的时候,一个开发团队可能只有一名或者两名研发工程师。这时候并没有全面推行Scrum的必要,而可以借鉴Scrum中的一些做法。比如有道云笔记的Web团队最初就是这个情况。当Web团队只有一名研发工程师时,我们就尽可能地尊重他的工作方式。同时为了保证项目进度可控,我们引入了Scrum的sprint机制——以sprint为开发周期,每个sprint进行一次Web产品演示。这不但能够让工程师有一个以sprint为期限的压力,还能够让其他同事即时地了解项目的进展,以便做出相应调整。当Web团队扩充为两名工程师时,我们又引入了结对编程、持续集成、相互代码审核等做法。直到Web团队的规模进一步扩张时,我们才开始考虑全面启用Scrum。

当团队内无法找到合适的Scrum Master时,不要轻易推行敏捷。如果你的团队是由新人组成,或者即使有资深员工但是他并不了解或认同敏捷开发的话,那么你需要等待合适的Scrum Master出现。

合适的Scrum Master需要具备几个特质:首先,他要认可敏捷开发这种方式;其次,他要熟悉业务,起到教练的作用,能带领团队走正确的流程;并且,当团队遇到问题时,他要有能力和担当引导团队做出决定,在团队成员遇到困难时,他要协助成员解决;最后,他要能识别重要和紧急的事情,而并不是事无巨细的反馈到产品负责人那里。

敏捷开发虽然希望团队自我管理,但是这需要一个过程,开始的时候,一个合适的Scrum Master至关重要。有道云笔记的Web团队在成立一年多以后才开始推行Scrum,很大的一个原因是在培养合适的Scrum Master。依据我们的经验,最胜任Scrum Master的人选是技术主管。我们也曾尝试过让产品经理担任Scrum Master,但是由于产品经理本身往往担当产品负责人,兼任Scrum Master会影响他在产品机会和产品体验等方面的投入。

2、限制Scrum团队的规模,建立Scrum团队之间的协作机制。

随着业务的发展,团队会变大。这个时候不拆分团队的话,效率会变低。

有道云笔记移动端团队就经历过这样一个过程。很长一段时间Android和iOS的研发工程师组成一个Scrum团队,有共同的产品负责人和Scrum Master。但是随着移动端团队人数的增长,Scrum会议的效率却降低了。虽然Scrum会议只有不到半小时,但是当说一个平台的事情的时候,另一个平台的工程师会觉得无所事事。发现了这个情况后,我们把移动端团队按照平台拆分成了两个Scrum团队,以确保Scrum会议上说的是每一名参与者都关心的事情。总的来说,参加Scrum会议的所有人,包括产品、开发和测试,不应该超过9个人。

按照平台拆分团队,限制了Scrum团队的规模,提高了Scrum的效率。与此同时,多个Scrum团队之间必须进行有效的协作。

在初期,我们鼓励研发工程师通过面对面地商量,快速推进来处理平台之间协作的需求。但是随着业务的发展,这样的协作越来越多,也越来越复杂,这样面对面的讨论往往会疏忽细节需求。比如说,有道云笔记3.0版本中的待办事项功能,就需要PC、Web、Android、iPhone以及Server等多个Scrum团队一起,对这个功能进行产品定义和确定技术方案。这样复杂的协同需求需要额外的机制来保证。这个机制就是Scrum Master的定期会议。在这个会议上,我们会讨论各个Scrum团队相互依赖的项目,安排好各Scrum团队的开发顺序。对某一件具体的事情,其中的一位Scrum Master会被指定为具体负责人来驱动跨Scrum团队的协作。同样,只有当Scrum团队间的协作任务比较复杂的时候才需要引入这个机制。

3、产品经理和研发工程师要拥抱Scrum带来的变化。

在引入Scrum之前,一般的项目管理方式是版本式(瀑布式)的,产品经理决定下一个版本做什么,预期发布的时间,然后由产品负责人或者技术负责人来兼做项目经理。这个时候遇到的问题是项目往往会延期,但是产品经理会有一种对项目把控的感觉。

引入敏捷开发之后,这个事情变了,发布是跟着sprint走的。基于持续交付的原则,一次发布包含一个或者多个sprint的内容,而这些内容是由团队整体决定的,而不是产品经理个人决定。产品经理只是定义了功能需求的优先级,这些功能需求与代码重构、开发工具、以及市场运营等的推广支持等需求一起排期,最后由整个团队决定一个sprint做哪些东西。

从表面上看起来,产品经理对产品的把控小了,为此,团队一位资深产品经理有过质疑。最后,我们还是说服了他接受敏捷。事实上,接受Scrum并不困难。这样,产品经理可以把重心放在对产品需求的把握上,而不必整天问这个咋样了那个咋样了。而且,团队的开发效率,功能点完成的速度并没有因此而降低。

研发工程师同样要拥抱Scrum,调整自己的工作方式。Scrum不鼓励过度设计,而采用涌现式设计。这意味着开始往往不会把技术架构做得大而全,而是鼓励快速出成果。当然这并不是说程序架构能够设计得很糟糕,而是说不要花太多的精力在未知的事情上,小步快跑。为此,代码重构是必须的(编者注:在不改变软件现有功能的基础上,通过调整程序代码改善软件)。我们并不建议整个sprint都去做重构,更建议持续重构,把代码调整也分解成任务,每个sprint做一些。在一些大版本发布之后,重构任务的比例可以适当高一些。

4、量化衡量团队的执行力的指标:完成度、评估准确度、计划合理度

当Scrum团队不大的时候,可以依靠主观感觉来评估执行力。有道云笔记团队在初创的一年内,对sprint的完成情况是没有量化的评估的。

Scrum教材对执行力的量化评估用的是故事点和速率。由于团队成员实际上都是有道云笔记的用户,能够直观理解产品经理提出的需求。因此我们省去了用户故事,由产品经理提产品需求,而团队把需求分解成任务。经过一段时间的探索,我们定义了几个量化指标,其中最重要的是完成度,我们用这个指标来衡量团队的执行力:

完成度=1-计划内未完成任务的剩余时间/计划内任务评估时间

(完成度的数值在80~90%之间比较好。过高的完成度说明sprint计划过于保守。)

有些管理者会怀疑完成度的准确性:第一是,团队是否会把计划内任务的评估时间评估得过长,使得完成度看起来高?事实上根据我们的经验,团队对计划内任务的评估往往是偏乐观的;第二是,计划内未完成任务的剩余时间是如何出来的?这个是由团队在sprint末尾评估出来的,因为这时技术设计多已完成,这个时间是比较准确的。我们也曾尝试过燃尽图,发现并不如完成度来得直观。

另外,我们还定义了两个指标来作为辅助参考。一个是评估准确度(计划内任务评估时间/实际使用时间),一个是计划合理度(计划内任务使用时间/计划外任务使用时间)。这两个指标的历史数值可以让我们更加了解团队执行的情况。

当Scrum团队不大的时候,可以依靠主观感觉来评估执行力。团队扩大后,详细的数值评估必不可少。
当Scrum团队不大的时候,可以依靠主观感觉来评估执行力。团队扩大后,详细的数值评估必不可少。

5、高效的sprint计划会的要素:预先梳理需求、合适的任务粒度、随机认领任务、运营调研任务、任务评估。

Scrum开发中,最重要的会议是sprint计划会。但是在这之前,产品经理和研发工程师可以预先梳理一下需求,以保证sprint计划会可以更加高效和准确。我们尝试过多种方式来预先梳理需求:发邮件、产品与研发面对面沟通、开需求梳理会。哪种方式更好,目前还没有定论。

Sprint计划会主要讨论几件事情:将需求分解成任务、评估每个任务的工作量、分配任务。每件事情都有各自的技巧。

首先,任务分解的粒度应该如何?Scrum开发一般认为任务分解得越细越好,但是在实际操作中我们发现如果分得太细的话是有问题的。比如说,认领任务、记录每个任务的工时和完成情况,都会带来时间消耗。我们经过较长时间的实践,发现0.5至3天一个任务是一个合适的粒度范围。

如何评估工作量和分配任务这两个事情是关联的,不同的人做同一个任务,往往时间会相差很大。所以这时候有一个艰难的选择,是让大家做自己熟悉擅长的事情,还是随机认领任务以达到团队人员对所有模块都很熟悉的状态。一个短期见效,另一个长期可发展。

有道云笔记PC平台的Scrum团队经历了一个从前者转向后者的过程。在开始很长一段时期里,Scrum团队把自己PC客户端按模块进行拆分,每个模块由一位研发工程师负责,工作量的评估也以这个人判断为准。这个办法帮助团队快速开发了PC的第一个版本和后续几个小版本。但是慢慢的,这种做法的瓶颈就出现了。之前的模块划分随着项目发展变得有些过时,有的模块出现了瓶颈。在最近的几个sprint里,PC平台的Scrum团队已经开始随机认领任务的方式。

此外,在实际研发工程中,往往会有一些由于团队没有相关的经验而比较不确定的事情。对于这样的事情,我们会先安排一个调研任务,并且将这个任务尽量安排在sprint的早期,并且凭借经验会在计划会上留出后续实际开发的时间。如果调研任务确定这个事情的复杂度可控,我们会在后续的sprint会议上根据调研成果分解出详细的任务,另一方面,如果这个事情的复杂度太大,那么我们会把完不成的内容放到下个sprint。

任务评估的办法,或者用纸笔写下后同时公布或者用估算扑克,两者本质上没有区别。当有较大分歧时经过讨论后再次评估,次数不宜过多,一般1-2次就好,不超过3次。如果讨论不清楚,Scrum Master不妨先定一个时间,让会议进行下去。后面实际开发过程中会越来越清楚。敏捷开发本来就是渐进的过程。

6、流水化安排开发环节与测试环节。

如何安排测试与开发,是从项目一开始我们就反复思考和尝试的问题。经过一段时间的实践,我们目前采用流水化的方式来安排开发环节与测试环节。具体来说,就是在开发sprint结束后再开始测试这个sprint的产出版本;而在开发的sprint内,开发团队解决上一个sprint的产出版本测试出的bug。虽然这意味着开发团队要在测试环节还未开始之时(Sprint计划会上),就要估计并预留出上个sprint产出版本的bug修改时间,但在实际操作中,开发团队能够通过历史数据做出比较准确的估计。因此这种方式的效果是良好的。

7、版本发布基本按照sprint周期。

我们通常在一个或者多个sprint之后(在测试环节之后)发布版本。具体选取几个sprint往往会参考一些市场情况的考虑,比如说将一个做了较多重构的sprint与一个做了较多新功能开发的sprint打包作为一个新版本发布出来。我们基本上不会为某个大版本打乱我们的sprint周期。

8、Scrum需要配备合适的工程实践,例如单元测试、代码审核、持续集成、项目管理工具。

我们要求研发工程师必须要写单元测试和相互审核代码。测试驱动开发和结对编程目前还有许多争议,我们也不建议贸然尝试。在实践中,我们采用了简化版本,对可以写单元测试的模块都要求测试覆盖,并且通过测试覆盖率来量化单元测试的力度。此外我们将研发工程师两两结对,相互检查对方的代码,只有经过检查的代码才能最终提交。

此外,我们对代码进行了持续集成。每天凌晨持续集成系统会自动下载前一天的代码,进行编译和部署。Web端会直接部署到Web测试服务器,而客户端(PC、iPhone、iPad、Android)会自动拷贝到一个内部服务器上。测试人员或者感兴趣的人每一天一上班就可以用到最新的版本。

关于Scrum的任务管理,我们采用过不同的项目管理工具,包括白板、开源软件等等。总的来说,工具只是简化了一些统计,Scrum最重要的还是敏捷开发本身的思想。

本文曾发表于新浪科技 http://tech.sina.com.cn/i/csj/2013-01-22/18528003613.shtml