“结对编程(Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员。两个程序员经常互换角色。”
——维基百科
基于上面的描述,我们对结对编程有了大致的了解。从直观上看,它具有以下几大优点:
1) 互相学习。学习相互间的设计思路、开发技巧。
2) 互相backup。一人有事,另一人顶上。
3) 规避风险。通过及时沟通,促使问题尽早暴露并解决。
除了以上能直观感受到的优点,其它隐性的优点也有非常多,这里不详细叙述。纵观有那么多的优点,但真正在项目过程中有结对实践的却很少。究其原因不难发现,现实环境很符合或者达到这种“天时、地利、人和”的要求。最突出的原因可能有:
1) 团队资源有限。结对编程需要投入更多的人力资源。
2) 人员能力不齐。项目组成员能力参差不齐,不协调的配对起不到1+1>2的功效。
3) 效率问题。不适应结对编程,会严重降低开发效率。
除了上述原因,大家可能还有众多不去选择它的原因,在此不一一叙述。我们项目组为了能达到结对编程给项目带来的诸多好处,决定采用结对编程的方式。但根据团队所处环境,对以上定义的结对编程稍微做了变化。
项目组现状(截至2012年11月底):
人员配置:1PM + 4开发 + 0.5专职前端 + 1PD
支持产品:运营work平台、报名工具、标签体系、自动化专场、调研系统
支持小工具:BU属性管理、发票奖罚管理、工业品会员管理、优质供应商池、类目导航等
截至2012年11月底,项目组总共7人,其中全职开发4人。支持5个大产品及多个小工具,人均开发和维护2个产品或小工具。
在繁重的任务及业务压力下,如何让项目组全体同学尽可能熟悉所有业务,了解相互间的代码,提升开发效率的同时并保证项目质量,是项目组全体同学需要去重点考虑的。基于以上情况,我们决定采用结对编程,但共享一台电脑进行结对编程是一种奢望。于是有了下面这个,进行调整过的结对实践。
1、 结对开发
项目组4位开发两两结对,共同完成开发任务。开发前,结对同学对需求进行详细分析,并通过充分沟通讨论,对需求进行必要的设计,同时输出设计文档。紧接着两位同学相互认领、划分各自的任务,根据之前讨论设计的内容进行开发。开发过程中,有其中一人开发顺利或者其中一人遇到麻烦,两人之间相互协调,一起去完成任务。
图1 结对讨论、分析设计需求
案例: 1212大促前夕,林录生和王小军结对组的情况。需求任务中有大促的紧急需求以及其它相对不紧急的需求。他们俩经过讨论、分析,最后各自认领、划分了任务,其中王小军的任务中有大促的紧急需求,林录生的任务相对不紧急。在开发过程中,因为大促需求有了点变化,王小军开发的任务在时间点上跟预期可能有所延迟。经过再次讨论评估,林录生马上加入王小军开发的需求中,一起开发,最终共同完成了预期的任务。
2、结对组交叉review、测试
当开发完成后,结对间就会进行交叉review及测试(如图2),保证项目质量的同时,熟悉相互间的代码及业务。
图2 结对间Code Review
除了结对间的交叉测试,结对组与组间的测试也会进行。迭代计划中留有1天做集成测试,在这一天除了完成发布前的准备工作,结对组与组间会进行交叉测试。确保业务质量的情况下,尽可能的熟悉结对组与组之间的业务,达到共同熟悉业务的效果。
3、结对组与组之间的协作
除了上面提到结对组与组之间交叉测试外,组与组之间的协作也必不可少。如某一个结对组由于种种原因导致需求任务可能延迟,另一个结对组根据需要介入需求,为了项目组共同目标,一起努力完成任务。
案例:迭代项目正如火如荼地进行中,突然在开发期间有一位同学离职,黄晓童的结对组面临解散,而晓童也只能单兵作战。之前手中的需求任务,有一部分面临停工的危机。项目组经过讨论评估,确定遗留需求的优先级,并及时告知需求方项目出现的问题以及中存在的风险点。与此同时,发现另一结对组本次的开发效率高,开发进展顺利并预估可以提前完成。于是另一结对组介入,接手遗留的任务,紧急规避了风险,最终达到项目预期目标。
结对编程在项目组已经实践了一段时间,从项目组结对同学反馈的效果基本符合预期。整体需求的熟悉程度相比之前有大幅提升,相互间的代码也更加了解,更重要的是项目组成员的压力相比之前也有较大幅度下降。当然结对还在不断地实践中,我们也在不断地从实践中吸取经验,不断改进。