《反对结对编程》?别吧

最近在网上冲浪时看到了一些关于结对编程的讨论(争论),起因是一篇题为《反对结对编程(Against Pair Programming)》的博客文章,在文中,作者认为结对编程不仅仅是低效率的,甚至还是有害的,主要原因有:

  1. 结对编程时,程序员们更倾向于提供那些更应该在设计审查或者代码审查中提出的反馈,整体设计应该是在写代码之前就已经确定下来的,所以留给结对程序员们的就只有对细枝末节和代码风格的计较了,这些都会拖慢速度。
  2. 专家程序员和新手程序员结对时,专家会变得同新手一样“慢”。
  3. 从知识传播的角度来说,相对于可以1对n地进行知识传播的代码审查、设计审查和通用文档,结对编程只能1对1地进行知识传播,且代码审查等协作可以异步地进行。

关于引用文章在推特上引起的讨论: Matt Rickard’s twitter

我之前也对结对编程进行过一些简单的研究,客观地说,结对编程确实有着一些缺陷,包括上文所提到的知识传播的效率问题,另外还有其没有提到的结对编程在灵活性上的问题——实践中不可能永远把两个人捆绑成一个人用,也不总是能够找到较为合适的两个程序员进行结对,并且,结对编程也是需要进行一些学习和训练才能取得比较好的效果。

但是,结对编程绝不是引用文章所说的那样一无是处甚至有害,相反,其在很多方面具备着不可替代的价值。

首先,结对编程是一种非常强力且深入的协作方式,在结对编程时,两个开发者会实时地、持续地进行交流,这个过程中,很容易产生高价值的反馈(比如捕捉到一些隐藏比较深的bug,或是一些可能有性能隐患的缺陷等),因为双方都处于比较专注的状态,对问题的理解也在一个频道上。
一个最直观的场景是在故障排查时,两个人或者更多人共同地去解决一个问题,效果一定是大大好于自己一个人闷头去琢磨的。

而结对编程中对于“细枝末节或代码风格”的斤斤计较,也未必是有害的,因为这些细枝末节并不会拖累结对程序员的速度,一个更准确的更易于理解的变量名,一行简短的注释,又或者一个简单的封装,这些反馈被提出的时机正是在开发的实时进行当中,解决它们通常也就是顺手几秒钟的事情,这不会“拖累”任何人,而如果能频繁地持续地去除代码中的晦涩之处,让代码变得更容易理解,更优雅,又有什么不好呢?

的确,1对1的结对编程,相对于代码审查、设计审查和文档,其传播知识的效率也许是比较低的,但是效果却是非常好的,审查别人写的代码,又或者查阅一些省略了大量细节甚至有可能还过时了的文档,哪里会比得上亲身深入而专注地参与到代码地编写中去呢?

资深开发者的速度在和新手开发者结对编程时会有所降低,但是为什么要对新人开发者在这个过程中获得的成长视而不见呢?新人可以在结对编程中有效地学习团队中的流程和工具,学习相关的业务知识,学习资深开发者的高超技艺和思路,况且即使资深开发者也是经常能从结对中学习到东西的,难道团队成员的能力提升是没有价值的吗?

最后,最让我无法理解的是作者在文中的这么一段话:

Let’s start with the economics. Since we are employing two programmers to do work on the same keyboard at the same time, the output of pair programming must be greater than 2x the output of a single programmer to make sense.
(从经济上讲,既然我们雇佣了两个程序员同时在同一个键盘上工作,那这对程序员的产出一定要高于单个程序员的2倍才合理)

我无语,这是什么种植园思维啊,即使不提这种话背后的血腥味,现实上,这个结论也是不成立的:合适的结对编程实践是能够产生相对于独立编程2倍以上的产出的(除非把“产出”等同于代码行数而不考虑其质量也不考虑对团队能力的提升等),而且,即使,如果结对进行故障排查只能缩短30%解决故障的时间,如果结对编程只能让新加入团队的成员提前30%的时间到达最高生产力,这难道不值得去做吗?

我经历过大约两年实践的结对编程实践,在那期间,从结对的同伴那里我学到了很多很多非常有价值的宝贵的知识和经验,这些都令我受益匪浅。感谢他/她们没有像引用文章的作者一样,把我当成拖慢自己速度的累赘。
对于团队来说,我的看法是结对编程这种实践有着其缺陷,也需要一些学习和训练才能做得够好,但是如上文所说,其所提供的价值也是十分显著的,也许可以根据团队的具体情况具体实践,比如在故障排查和新成员加入团队时完全实践,而在平常开发时,只安排一定比例的开发者结对工作在那些较为重要的功能开发中。 无论如何,我认为,如果要拒绝结对编程,一定要在清楚地认识到它的价值后,再有一个不得不拒绝它的理由。