本实践是原阿里巴巴ITU内贸团队打造出的一系列适合团队不断精进的敏捷实践。阿里内贸团队是一支自组织,一体化和全功能的敏捷团队。自组织体现在团队中的每个成员都会得到充分的尊重和自由,每个成员都可以主导某个实践(如项目回顾会议)和改进 (如推动团队成员一起提高单元测试覆盖率)。一体化体现在团队合作上。全功能体现在团队成员既可以研发,也可以做前端和测试,从而打破角色边界提高总体产 出。我们在进行一次敏捷实践时会经历五个步骤,分别是计划,编码,测试,发布和回顾。注:本图由同事金建法所画。
本系列文章尚未完成,其他实践正在编写,如果你有任何疑问欢迎交流,我们会在后续的文章中进行补充。如果你觉得这个系列的文章不错,也欢迎分享。
本文中,来自阿里内贸团队的工程师分享了所在团队打造合作型“精英”小团队的敏捷实践方法,同时讲述了实践的效果,旨在给大家一些启发,以供参考和借鉴。
能打造出Facebook里所提倡的“精英团队”固然非常好,但这样会对团队中的每位成员都有较高的要求。我所在的团队希望通过将团队合 作精神运用在项目的各个阶段来打造出一支强有力的合作型小团队,并且取得了很不错的战绩:每两周发布一个版本,完成了几次零Bug的项目,实现了一年线上 零故障。
我们团队由2名产品经理、6名开发人员和2名QA组成,并根据团队特点量身定制了一套敏捷的开发方式。本文主要分享在需求、设计、开发和总结等阶段中如何提高团队成员的合作意识,从而形成团队合力的最佳实践。
提倡需求串讲。上游的质量决定了下游的质量。在软件开发中需求文档属于最上游的输出,所以我们格外重视需求评审。为了让团队成员能充分理解需求,并 提高团队 成员的参与度,项目需求不能总由产品经理来讲解,而应采用轮流讲解的方式,每次迭代由不同的人员讲解。需求文档会提前发给所有团队成员,请大家消化和准 备。在进行需求评审时选某一名成员上台讲解需求。虽然需求评审最核心的任务是在“评”上,但如果团队成员都不能很好地理解需求或者不能很好地参与到需求评 审上,是很难做好需求评审的。
为了提高设计和评审的效率,并且能够让全员充分参与到设计和评审中,我们团队提倡结对设计、简单设计、交叉设计和全员参与设计评审。
评审时间要短。因为大部分人在会议中只能专注20分钟,所以设计评审要在40分钟内结束,设计者可使用PPT或直接在黑板上画出设计思路。让参与者 充分了解设计的模块。如果是对已有功能的修改,设计者必须先讲这块功能原来什么样,现在需要修改成什么样,涉及哪些修改点,是如何设计的。这能让其他模块 的设计者更了解这个模块,参与到这个模块的设计评审中。
如果设计方案审批没通过,则需要设计者返工。为了提高效率,不需要再开一次会议评审重新设计的方案,将相关人叫到座位旁边确认就可以。
晨会通常用于汇报工作进度,而我们希望将打造成寻求团队合作的会议。很多时候,项目质量低下主要是因为团队成员开发时间不够。如果某位成员实现某个功能发生 了延迟,那么他肯定没时间写单元测试,更没有时间帮别人做Code Review。此时,就应该在晨会上将这个问题告知团队其他成员。我们不会因某名成员实现功能延迟而责怪他,更不会让他加班追赶进度,而是在晨会时请其他 团队成员帮他完成单元测试和Code Review。我们是一个团队,有问题绝对不会让团队的某名成员独立承担。
这些方法不是团队创建之初就有的,是通过每次项目总结和下个项目实践不断精进出来的。在做项目总结时,所有成员都要针对本次项目的不足提出下个项目需要改善的地方,定出下个项目中可尝试的实践,并确定一位负责人和完成时间。
根据经验,如果不确定负责人和完成时间,任何实践基本都很难完成。另外,我们通常只定一个实践在下个项目中执行,定多了也很难完成。而且为了让大家能够在项目总结会议中畅所欲言,通常会将项目总结会议办成一个茶话会的形式。
在项目开始前,开发人员和QA会轮流坐庄,赌本项目的Bug数会是多少个,输的一方要给赢的一方买饮料喝。这么做主要是为了在提高项目质量的同时培 养团队合 作意识。如果开发要想获胜,那么团队中的每名开发人员都尽量不要产生Bug,避免拖累整个团队,而团队的其他成员为了实现目标会更加主动地帮助同学做 Code Review。但这个目标必须定得非常合理,如果项目中涉及到大量的前端开发,则Bug数会更多,目标要定低一点。在本次项目目标达成之后,下一个项目会 定更高的目标。
实现团队的自组织管理,非常有助于团队形成合力,极大地提升团队整体的工作效率。本文结合原阿里ITU内贸团队的敏捷实践经历,阐释了何为自组织管理、为什么进行自组织管理、如何进行自组织管理等内容,同时给出了团队实施自组织管理的效果。
在《射雕英雄传》里,以全真七子的武功是打不过东邪黄药师的,但当他们摆出了“天罡北斗阵”时,却能和黄药师打成平手。这就是团队合作形成合力的威力。
自组织管理是原阿里ITU内贸团队采取的一种敏捷实践,该实践旨在帮助团队成员加强团队合作,形成团队的合力,从而提高团队整体的工作效率。
我们提倡的自组织管理是指团队中的每一位成员都是团队的Owner,都为团队的目标负责,在团队事务上没有一位绝对的管理者,每位团队成员都可以作为团队事务的管理者,组织团队中的所有成员一起完成团队事务。
传统管理指的是在一个团队中由一个人负责团队的管理,而其他成员不参与团队事务的管理,管理者发布命令,团队成员执行命令。这样的管理存在诸多弊端。
传统管理对于团队事务很难做到面面俱到。要创建一个优秀的团队,需要管理的团队事务非常多,例如项目管理、组织团队建设活动和团队分享活动等。如果仅由一位管理者来负责管理很难全部完成。即使全部完成了,由于没有充足的时间进行过程管理,其结果也会打折扣。
传统管理执行力不够。在传统管理中,主管是指挥者,发布指令,团队成员是指令的执行者。但团队成员是人而不是机器,他们都有自己的想法,有时对于自己不认可的事情,即使内心不愿意,迫于主管的权利也只能执行,而这样做事的话往往执行力不足,经常需要主管的督促。
传统管理很难充分发挥团队合力。团队的合力在于每位成员都在积极主动地为团队目标付出自己的一份力。团队中经常有一些较积极的成员会提出一些好的建 议和想 法,比如希望一起做某个工具,来提高工作效率,他们希望主管认可其想法,并能组织大家完成这个想法。但在传统管理中,或者因为主管认为这个想法没有价值, 又或者因为管理者没有时间来组织这件事情,导致这些想法最终没有落地,于是利于团队工作的想法就会越来越少,最后只有管理者一个人来思考如何提高团队的工 作效率等事情。
为了消除传统管理带来的弊端,我们团队尝试进行自组织管理实践。让团队中的每一位成员都参与到团队事务管理中,让某些方面表现出过人之处的成员,管理其擅长并感兴趣的团队事务。
比如让喜欢旅游和娱乐活动的成员负责团队建设活动;让擅长写单元测试的成员组织大家一起提高单元测试覆盖率和质量;让擅长项目管理的同事负责项目管理;让对项目管理有兴趣有想法的同事负责组织大家开发开源项目;让喜欢写作和分享的同事负责打造团队分享的氛围。
目前,我们团队还没有实现高度的自组织管理,主要由主管向团队所有成员分配团队事务,然后团队成员组织大家一起完成这项团队事务。而组织的形式采取任务发布和认领的方式。
组织者把团队事务分解成若干子任务,并制作成一张任务认领表放在confluence上让所有感兴趣的成员去认领。表1是一个典型的任务认领表,有些任务需要注明任务的详细信息。
领取的时候必须写上计划完成时间。实践表明,领取任务的同学自己写上计划完成时间会有一种无形的督促力,能够提高任务的完成度。
另外,分解出来的子任务需要的时间越短越容易被领取。我们通常划分出来的一项子任务只需要1天左右的时间就能完成,完成了以后可以继续领取其他子任务。如果有些子任务没有人认领,组织者一般会去认领这些子任务,或者主动询问其他没有认领的同事有无兴趣认领这项任务。
组织者不仅负责任务的分配,更应该2促进任务的完成。比如组织提高单元测试的同事会针对比较难写的单元测试Case写一些分享文档,帮助大家攻克难写的单元 测试。如果在做某项子任务的过程中出现了问题,组织者要主动帮助他们解决问题。还需要对于所有的认领者给予适当的激励。比如,每个模块完成时在团队群里发 一条表扬的通知,或者请按时完成任务的同事喝饮料,以激励和提醒其他同事按时完成认领的任务。
3.3.3 鼓励每位成员都组织一项感兴趣的公共事务
如果只有一位团队成员组织公共事务,那么领取任务的积极性可能不会很高。而如果团队中的每位成员都组织一项公共事务的话,积极性就会高很多。
因为人都有互惠心理,当你支持其他同事组织的团队事务时,别人就会主动支持你组织的团队事务,这样无形当中就形成了一种积极合作的氛围,从而推动所有公共事务的进展。
主管在自组织管理中充当着支持者、协调者和指导者的角色。一支传统管理团队向自组织管理团队转型,需要主管的大力支持和帮助。
主管不仅需要口头上支持组织者的工作,比如在周会上鼓励团队每位成员去认领任务,更要在行动上支持组织者的工作,比如首先认领组织者划分的子任务。
主管管理的目的应该是帮助团队顺利完成工作,并且帮助团队成员快速成长。因此,当主管听到团队中一些积极的同事提出好的想法时,只要这个想法符合团队目标,应该尽量帮助他完善这个想法并支持他去做。
而对于不合理的建议,也应该帮助团队成员进行分析和思考,帮助他思考出这个建议不合理的原因,并使他的思考更加成熟和正确,以期望下一次能提出更好的建议。而不是没有仔细思考这个想法就拒绝了。如果贸然拒绝的次数多了,团队中积极的想法就会越来越少。
肯定了团队成员的想法后,很多成员都会想自己去把这件事情做成,这时主管应该鼓励他采用团队合作的方式。让他分享这件事情,看看团队中是否有同学有兴趣一起做。这样不仅能快速地使这个想法落地,而且提高了团队的合作能力。
从传统管理向自组织管理转型的过渡期可能会出现一些问题,因为很多团队成员可能由于缺乏管理经验,造成项目延期或故障。这时主管应该主动承担责任, 通过这种 方式信任和保护团队成员,使团队成员积极努力地把自己负责的管理职能做好。否则,一旦有问题,团队成员可能就会猜疑,甚至抱怨这种管理方式是否合理。
进行这样的自组织管理,不仅需要管理者的大力支持,更需要每位团队成员的配合和支持,所以培养团队合作氛围和团队管理能力尤其重要。
因为我们进行自组织管理的团队事务都倾向于通过团队合作来完成,不提倡单兵作战,所以自组织团队必须有很好的团队合作氛围。
在招聘时,我们倾向于招聘喜欢团队合作的成员加入团队。在工作中,通过一起解决问题来提高团队合作氛围。比如,如果晚上将发布软件的某个版本,而团 队中的某 个成员开发的模块有点问题,团队成员会一起加班来分析并解决问题。在工作之外,团队会经常做一些非零和博弈活动来培养团队氛围。比如一起吃午餐、打桌球、 打牌和唱歌等。
因为自组织团队需要每位成员都参与到团队事务管理中,所以需要培养团队内的每位成员都有一定的管理经验。对于缺乏管理经验的成员,可以先让他们做一些简单的管理事务,如团队分享管理和团队活动管理等。
在自组织管理中,团队中的每位成员既是管理者,又是执行者。每位成员管理着自己擅长并感兴趣的事情,这样事情通常都能很好地完成。而且团队中的每位成员都能站在管理者的角度来思考问题,增加了团队成员之间彼此的理解,工作效率自然有所提高。
我们团队通过自组织管理完成了诸多团队事务,例如开发了一个Eclipse Code Review插件Tala,完成了单元测试行覆盖率70%、整个系统的功能导航图等。
自组织管理的最大特点是弱管理,鼓励团队成员自我管理,主动思考,多担当。团队成员具有强烈的自我驱动、自我完善、自我管理的意识,不仅能主动支持团队的公共事务,并且还能主动发现团队和业务中的问题,对这些问题提出改进建议,努力解决这些问题。
我在工作之余翻译国外的并发文献时,也运用了这种自组织管理方式来组织翻译活动。我在论坛发帖,目前已征集到十几位爱好者,翻译完成几十篇并发编程的译文,对翻译完的译文进行了互相校对。这样的形式比我一个人翻译要高效很多。
本文主要从提升项目质量、促进知识传递及减少项目风险等角度出发,讲述作者所在团队在结对编程实践中的一些经历,以及如何避免或减少其所带来的负面影响。
你了解结对编程吗?你尝试过结对编程实践吗?也许你还未曾尝试甚至还不曾了解,那么我们一起来学习和了解敏捷结对编程实践,相信对敏捷感兴趣的你会有收获。
结对编程(Pair Programming)是一种敏捷软件开发实践,指两个程序员并排坐在一台电脑前,面对同一个显示器,使用同一个键盘和鼠标一起工作。一个人输入代码, 而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员), 两个程序员定期互换角色。他们在一起完成需求分析、系统设计、编码、单元测试、整合测试(Integration Test)、写文档等工作。基本上所有的开发环节都一起肩并肩地、平等地、互补地进行工作(如图1所示)。
上面是极限编程(eXtreme Programming,XP)对结对编程的描述,它有如下主要的优点:
尽管结对编程有诸多诱人的优点,但实行结对编程实践的却为数不多,其主要原因可能有:
结对编程是颇具争议的敏捷实践之一,除上述一些优缺点外,可能大家还有更多不同的看法,但分析利弊不是本文所要讨论的重点。
就我所在的项目团队而言,6人左右的开发团队需要支持多个中小型独立产品的需求开发,在繁重的业务压力下,用户价值的快速交付是首要的,所以想尝试 共用一台电脑进行结对开发的实践只能是一种奢望。让团队开发人员尽可能熟悉相互间的产品代码,提升项目开发效率以及保证良好的项目质量,是我们在项目开发 过程中需要重点解决的问题。
我们试图通过集体Code Review和设计交流分享等活动,来提升代码质量以及相互间业务代码的熟悉度,但一直收效甚微。问题主要在于这种集中式活动时间较难安排,人多交流效果 不佳,性价比不高。后来,得益于公司的导师机制,在一对新人和导师身上,找到了敏捷结对的原型。由于他们的紧密合作,遇到问题及时沟通,新人在项目进度和 质量都有不错表现,很好地融入了团队。在后续的项目过程中,我们不断地尝试和优化这种结对形式,逐渐形成相对固定的工作方法。
与XP结对编程相比,敏捷结对编程最为显著的差异是结对进行需求分析、系统设计和问题讨论,但分别编码实现,通过过程中频繁的Review来实现结 对的效果。开发人员两两结对,共同认领开发任务,一起对所承担的开发任务负责。在需求理解、设计阶段双方一起设计和讨论,然后分工各自编码实现,并通过 Code Review以确保实现与设计一致。对结对过程中发现的问题,随时沟通和讨论。由于产品业务逻辑相对不是特别复杂,所以通过这种小范围、高效的沟通,可以 解决项目中的绝大部分问题,实现更高的开发效率并确保代码质量。目前,在开发流程中的主要结对活动如图2所示。
结对活动(如图3所示)给我们带来了哪些好处?
无论新老结对还是强弱结对,都要尽力避免一方对另一方产生依赖,要给新人足够的成长和锻炼空间,让其独立思考和解决问题,并允许在可控范围内尝试失败,以获取宝贵经验得到成长。否则,团队只会多一个执行者,结对难以达到预想的效果。同时,一定程度的独立活动,可以让大家保留自己的工作习惯,而且形式 更为自由和灵活。当然,大家可能会有疑问,如何保证结对人选中资深工程师工作的正确性,因为新人和弱者很有可能无法提出想要的Review帮助。这个问题 在我们的结对中不可避免,有选择地邀请其他资深专家Review,也许会是个不错的解决方案,特别是对于一些重要的复杂业务逻辑。
参加结对的工程师应具备独立思考和解决问题的能力,并且具备较好的团队协作意识。否则,不仅不能有好的结对效果,反而会带来一些新问题。此外,结对也不仅限在研发工程师之间,研发和测试工程师之间或同产品经理之间的结对(如图4所示),同样可以带来不错的效果。
引入敏捷实践,贵在充分理解、结合实际,能扬长避短,且是一个适应、发展的过程,而按部就班绝对不是个好主意。有选择地结对对我们来说也许是上策,在结对的人选、场合、结对的环节等方面进行选择性的实施。
回顾(review)是敏捷开发中的一个必不可少的实践,也是把整个敏捷开发过程连接成一个闭环的关键节点,本文将阐述我们是如何做敏捷回顾的。
无论我们发现了什么,考虑到当时的已知情况、个人的技术水平和能力、可用的资源,以及手上的状况,我们理解并坚信:每个人对自己的工作都已全力以赴。
唉,又要开总结会了…每次时间都那么长问题讨论来讨论去就那几个,没啥新意都不记得这段时间做过啥了新迭代KO,总结放在一天时间太紧我们敏捷回顾会议内容
目的:通过分析用户数据来看我们的产品设计是否赢得了用户的认可
做法:收集前一迭代上线后的相关产品数据,如新功能使用日UV、PV等,当然如果发布后第二天召开回顾会议,可能不能马上收集到相关数据,也可以分析上上迭代的新功能使用情况。
通过项目过程数据来看质量
集成测试可以通过集成测试框架如Hudson,主要关注单元测试覆盖率,通过率以及注释率等指标,如下图:
目的:总结项目中做的好的,不好的
做法:从KEEP(做的好的,要保持的),CHANGE(做的不好的,需要改进的),TRY(可以尝试的)三个方面进行总结。首先回顾下上次总结会 议列出来的CHANGE和TRY事项,看看前一迭代做的怎么样;接着总结前一迭代的情况(每个团队成员在回顾会议前都先想好,写到便签条上,防止说的时候 人云亦云),将每个人说的汇总,并由大家投票列出哪些可以在下一迭代中改进以及尝试,列出具体的action,建议不要多余三项,否则太发散什么都做不 好。如下图:
目的:督促项目成员自己做总结,看有哪些收获和遗憾,不仅要项目成功,成员也有要有所成长,也便于项目经理后续的任务安排有所侧重
做法:成员轮流发言,总结自己在前一项目中的收获和遗憾,尽量具体,收获指的是工程师在技术方面学到了些什么,总结了才会有成长,遗憾则指的是项目启动时给自己设定的目标或计划没有完成的。
以上就是我们敏捷回顾中的4个部分,在组织会议上可以适当采取轮流主持,以及准备些水果、零食,利于大家保持放松,经过前一个迭代的紧张开发和测试,通过敏捷回顾稍作休息,整装待发。