结对编程的正确姿势,你会了吗?

过去十多年中,笔者曾经与上百个开发团队共同合作,这些团队具有一个共同的特点就是:他们通常不会采用结对编程作
为软件交付的技术。其中一些团队会讨论结对编程并且认同这种理念,不过由于某种(些)原因,他们目前仍未采用结对编程。那么接下来的问题就是,是什么原因
导致他们不采用结对编程呢?在我个人的经验当中,采用结对编程和协作仍有许多障碍。许多团队合作(cooperate)的很好,但实际上并不是协作
(collaborate)。因为协作基于信任,它是结对编程的关键环节之一。

2015年度Review已经拉开帷幕,今年你都收到了哪些醉人的反馈呢?和往常一样,作为开发的我听到最多的话题当属结对了:

结对编程是软件开发过程中所使用的一种技术,两名程序开发人员共享同一台工作站,其中一名开发人员被称为驾驶员(Driver),另一位被称为领航
员(Navigator)或观察员(Observer)。两人轮流使用同同一个键盘编写代码和测试案例。两个开发人员轮流使用键盘可以让每个开发人员都有
机会思考设计和相应的实现。两人还能够从相互的思想交流中受益,通常能写出更加高效的代码。

“我的小伙伴总拿着键盘不放,只听过麦霸,来到骚窝竟然还有键霸!”
“我总算明白为什么面前会有两个键盘子了,如果再给我一次机会(请用湖南话脑补)”
“我不知道我的小伙伴在做什么,我跟不上,很沮丧,要不玩会手机算了”
“我的小伙伴特别忙,有时候一天也找不到,我怎么办…”
“我的小伙伴是个急性子,总说‘XX你做的太慢了,客户着急要,还是我来做吧’”……

结对编程的概念相当简单明了,而且在90年代后期,极限编程(XP)的早期就已经开始有实际的应用。不过在我个人的经历中,它仍是使用最少的极限编程技术之一。敏捷实践和极限编程的流行让这一问题得以回避。据我的了解,结对编程仍存在许多障碍。

那么结对时,你的小伙伴碰到这样的问题怎么办呢?当你遇到键霸、手机哥、上网君的时候怎么破呢?

我们首先从组织层级开始分析。许多经理觉得开发者结对编程时,他们付出了两个开发人员的代价却只得到了一个开发人员的生产力。在团队刚刚开始结对编
程时的确如此,不过只需经过很短的时间,结对就会以更快的速度交付更多的功能,而且经常只需要更少的代码,而且质量也会有一定的提升。结对编程能够帮助在
进行测试之前就解决掉代码中的问题,遗留到生产环境中的会更少。

在展开之前让我们先来回顾一下结对编程的前世今生是什么。

但组织级的挑战并未到此为止。还有一些关于实际环境方面的考虑。如今,开发人员通常会占据一个受限的工位空间。结对则需要至少6英尺大的开放式座位
空间,以便两人可以并肩坐在一起。有些组织还缺乏适用于结对编程的硬件,例如无线键盘,无线鼠标,以及至少21寸的显示器。对于显示器来说,则是越大越
好。

结对编程

极限编程是由当时Smalltalk
领域的大师级人物 Kent
Beck
在1996年受聘领导克莱 斯勒公司的一个综合工资项目开发 C3(Chrysler
Comprehensive Compensation)中 首次采用,
并于1999年10月出版的《解析极限编程》一书中正式提出了这一软件开发方法,而我们今天要讨论的结对编程则是其中一项核心实践。
极限编程中的“极限”(Extreme)是指将我们认同的有效软件开发原理和实践应用到极限,
如:
“如果集成测试很重要,那就要在一天中进行多次集成,并且反复进行回归测试”,所以我们要做持续集成。结对编程在提出时更多的是强调
“如果代码评审很好,那么我们就一直进行代码评审”,所以我们要做结对编程。简单讲,结对编程就是由两个程序员用同一台电脑完成同一个任务,由一个人负责编写代码码,另一个负责审查代码,从而能够时时刻刻的进行代码评审。
但问题来了,原先一个人工作,现在两个人了。“原来我自己写就好了,现在多一个人我还要给他讲,多浪费时间啊”;“我也讲不明白,我就是喜欢写代码而已,别逼我”(请自动脑补一个新人和一个不耐烦的老手一起编程的感觉)。这让我想起了美国AT&T公司贝尔实验室的Bjarne
Stroustrup博士说过的一句话:

设计和编程都是人的活动。忘记这一点,将会失去一切。- Bjarne Stroustrup

从极限编程诞生到今天的26年历史中,如果说持续集成是应用最广泛的一个实践,那么我认为结对编程则是最具争议的实践(没有之一)。其实这也间接印证了当时Kent
Beck提出的关于“极限编程是一种社会性变革”的说法。在现代互联网如此多变和快速响应的软件行业趋势下,事实已经证明软件从此不再是一个人单打独斗的工作,而是要求越来越多的多角色多任务的协作。软件行业的工作者必须要有比以往更多的沟通和协作技巧。而这对于习惯了一个人的软件开发者而言是一个巨大的挑战,必然要有一个改变和适应的过程。这也是为什么结对编程会成为最具争议的实践。文章开头的那些现象都是一个人改变做事行为的必然过程,不信你去问一问那些老一点的骚窝,哪一个不是从抢不到键盘到键霸,又从键霸到键盘无键,键在心中的一个过程。
那么结对编程除了审查代码提升代码质量,还给我们带来哪些好处呢?

除了硬件设备之外,组织级的挑战还存在于对开发人员的认可、加薪和晋升的机制。组织对员工进行排名会严重限制开发人员有效地学习结对编程的可能性。
许多情况下,开发人员希望被视为超级英雄,以借此提升其在同事之中的级别。另外一个阻碍是绩效评估。很少有公司会将团队合作视为一项有价值的技能,更多的
是寻找能够拯救公司于危难之中的“超级英雄”。此外,一直处于在战术层面灭火模式的组织难以体会在结对编程过程中开发人员进行的技术和专业领域知识分享所
带来的价值。

结对编程的好处

第一:培养新人,促进沟通,提升团队整体能力。
通过结对,年轻的团队成员可以向其他小伙伴学习,包括快捷键、算法、语法、SQL、设计、解决问题的思路、做事方式等等,1对1面对面师傅带徒弟式的学习是新技能get最快的方式之一。
第二:更好的知识共享和信息交流,促进团队协作。
澳门新葡亰,结对中可以互相分享代码的上下文,交换对代码的理解,促进质量改进和团队协作,同时也使得代码集体所有制成为可能,减少团队对某些成员的依赖,降低团队风险。
第三:促进团队成员的沟通,提升团队凝聚力。
通过结对,成员间彼此熟悉,增深了解,从而能够更好的协作完成任务。

如果你的团队在尝试结对编程上仍保持谨慎,好消息是将结对编程融入到企业文化当中已经有一些公开的案例。其中一个例子是Menlo
Innovations公司,他们要求所有的开发人员每天都要进行结对编程。结对编程是其招募员工的条件之一。虽然这并不一定对所有人都是最优的方案,至少能起到一定的作用。

如何进行结对?

澳门新葡亰 1

为了达到结对的目的,保持结对有趣持续的进行,通常根据结对的双方经验不同和场景分为如下多种角色和合作模式:

1.领航员和驾驶员(Driver-Navigator) – 键霸出没请小心。
驾驶员编写实现当前任务的代码,而领航员需要引领代码的编写并负责审查代码。除此之外,领航员通常还要考虑当前的实现方法是否正确,是否有别的做法,它是否会影响到其它功能模块,下一步是什么。驾驶员的主要任务是跟上领航员,负责完成代码的编写,保证代码质量。需要特别指出的是,微小的语法错误,多一个空行等错误,IDE会帮助我们纠正,是驾驶员关注的职责,而领航员只需进行提醒,结对时无需将此作为主要关注点。
合作场景:适应于各种组合,尤其一老一新组合。

2.乒乓模式
这里需要提及极限编程的另一实践:测试驱动测试。结对双方可以一个人编写失败的测试,一个人写实现通过测试;然后交换角色,不断循环。对于结对双方经验相当的情况下,由于交互和交换的频率很快,就如打乒乓一般,所人们戏称这种方式为结对的乒乓模式。
合作场景:适用于各种组合,尤其双方经验相当的场景。乒乓模式由于它的角色分工清晰,交换频率相对较快,所以乒乓模式可以帮助精力不集中的小伙伴快速融入,也是避免键霸出现的一个很好的方式。

3.鼠标和键盘模式
这是驾驶员和领航员的一种具体表现方式,其中一方使用鼠标,是领航员;另一方使用键盘完成代码的编写,是驾驶员。
合作场景:适用于一老一新组合。
有统计结果显示,好的结对工作效率是大于单兵作战的,能用较少的时间产生高质量的代码。那么为了保证结对的高效和高质量,我们还需要注意哪些呢?

让开发人员能够结对编程的一个关键因素是较高的安全系数。总的来说,绝大多数开发人员会担心被发现他们其实比他们所表现的要缺乏竞争力。有人将其看做是负担症候群的实例。负担症候群通常会出现如下症状:自己对自己的能力产生怀疑,而又极力说服其他人自己的确拥有这种能力。

几点Tips

1.多沟通。
有一个人的工作变成了两个人的事,小伙伴们就要彼此尊重,多沟通。如果有其他的任务要暂时离开,请及时告诉你的小伙伴,以便彼此更好的安排工作,保证效率。

2.确定开发任务列表(Tasking)
结对除了沟通,另一个挑战就是如何保持结对双方共同的开发节奏:一个小伙伴在做A功能,另一个小伙伴要做B功能。结对双方通过协商开发任务列表,能够提高对开发任务理解的一致性,确保开发节奏顺利进行。

3.定期交换小伙伴
定期交换小伙伴可以使得知识得到充分分享,每个小伙伴都有机会充当不同的角色,了解不同的知识上下文。与此同时,新的小伙伴的加入往往可以激发新的解题思路,或帮助发现问题,同时也增加结对的乐趣。

4.可持续的结对工作
真正的结对会比一人工作更专注,紧凑,所以一天8小时的结对会很累,因此结对需要定时的休息,保持合理的节奏。可与结对的小伙伴一起协商休息时间,比如一个小时或两个小时休息一次,从而保证可持续的工作。

5.多给新人机会
与新加入的小伙伴结对,需要耐心,多给予她/她上手的时间与空间。通常建议开始时多讲解,多展示,给她/他学习的机会;比如一开始可以由熟悉代码的小伙伴写测试,而新加入的写实现;随后可采用鼠标键盘方式或者乒乓结对方式。

6.勇敢加勇敢
对于新加入的小伙伴,如果跟不上的时候怎么办?要勇敢的叫停,打断结对的小伙伴,弄懂这个问题,这样做才是达到了结对的目的。曾经有人说我记下来回家去弄懂,我更建议及时弄清楚。就如前面提到的,结对是一个快速让自己学习和成长的机会;而且你的小伙伴通过讲解也会梳理自己的思路,能够更深入的理解这个问题或技术,互助互学。如果这个问题发现项目中其它成员也不懂的,那么我们还可以将这个对话扩展开来,分享给整个团队,提升团队的战斗力,所以更推荐及时解决,当然深度需要适当的把握。
如果结对的时候遇到键霸怎么办?作为新人自带消除键霸光环,勇敢的把鼠标默默的递过去,把键盘牢牢的握在自己的手中,“亲,辛苦了,让我试一下,我来!”。

7.反馈
就如戴明环一样,做事情的环要闭合,有始有终,有序循环螺旋式改进。而反馈往往是最后一环,也是最有效的一环,是帮助自己和结对小伙伴的必要工具之一,温暖的“小黑屋”是可以经常光顾的。

8.不是所有的场景都适合结对
对于那些结果需要维护,能够促进沟通、知识传递等价值的开发行为都建议结对,而诸如方案调研、一些非常简单的问题(微小的缺陷修复如拼写错误)等是可以不用结对的。

一部分人会认为代码审查已经
足够并且已经实际运转多年。代码审查的问题在于其发生在代码已经完成,而且常常是已经经过测试并准备发布时。如果发现问题,就会浪费许多编码时间,而且还
不得不重新返工并测试这个问题,之后再次经过审查。不幸的是,这在代码审查中时常发生。更有甚者,开发人员会陷入哪一种技术最佳的争辩之中。这种情形下,
要么最资深的人强制开发人员做出修改要么房间中最大的声音获胜。这两种情形都会破坏团队之中的信任感。

总结

结对并不阻止个人的独立思考,它给我们带来了诸多软件协作的好处,但结对也不是所谓的坐在一起就可以了。结对不是一成不变的,需要根据目前的任务灵活确定是否适合结对。
我认为想要做好结对,首要的是有效沟通。
一首打油诗说的好:
好结对成长快,互相监督与学习,感情信任日日增。
坏结对伤害大,手机上网人心离,团队早晚要散伙。
新人们不要怕,键盘牢牢握手中,勇气反馈早成长。
老人们不着急,系统把控在心中,沟通分享影响大。
有了这些姿势,文章开头那些问题你是不是已经有答案了呢?
题图来自网络,其它均由禚娴静提供。

当要求开发人员尝试结对编程时,他们可能会有颇有微词。譬如:‘如果我自己做速度会更快’或者‘与同事结对编程没有任何意义,因为我不会从他们身上
学到什么东西’或者仅仅是‘我已经尝试过了,但并没发现有什么作用’。尽管这些争辩可能是对的,但也可能只是他们感觉在有另一个人在场的情况下编程不安
全。

最根本的挑战在于如何创建一个能够让开发人员觉得可以安全地学习、犯错、快速失败、持续提升技能的环境。由于失败会遭受惩罚,一些开发人员会害怕失败。会对失败员工做出惩罚的组织不太可能鼓励员工尝试和成长。

网站地图xml地图