结对编程 VS 代码审查:对比开发者文化
| 2015-08-19 10:56 收藏: 2
从上一份工作到现在的这份工作,我从结对编程的开发文化过渡到同行代码审查,这个转变过程是一个非常有趣的经历。我认为我要记录下些我所注意到的变化。
你可以找到很多标题是/(结对编程|代码审查)的(利|弊)/这种样式的文章,这些文章的作者都可以给出一套清晰且有说服力执行方案。我认为只要权衡它们的利弊,这两种方案都是非常有效率的。我想就两者的权衡策略提供些相对客观的讨论。
专有名词的定义
因为“结对编程”和“代码审查”这2个名词都有很多种完全不同的解释,所以首先让我来定义下这篇文章中这2个名词的含义。
当我提到结对编程文化,我指的是一个几乎可以做到100%配对开发的团队。其实就是2位开发人员在屏幕前合作完成一项任务。一位开发人员操作,另一位指导。两位开发人员都参与到了代码构建的过程中。每天的编程,开发工作就是与你的搭档不断交流。一旦小组(2位开发人员)完成任务,完成的代码就直接提交给负责人且不需要进一步的审查。
当在会议室里大家紧盯投影仪上的代码时,代码审查文化可能会带给团队很多想法——至少对我来说是这样的。当然这不是我对代码审查的定义,这里我指的是借助自动化工具的同行代码审查的过程。通过使用像Gerrit Patchsets 或是 GitHub Pull Requests这种运行机制, 开发人员自行编程并将完成的代码提交给团队的其他成员进行审查。逐行注释是用来对代码风格、代码功能性进行质疑和评论的。一旦一项提交被审核通过,就会把它交给负责人。
成功的前提条件
两种文化之间其实有些无可争议的共同点:
- 稳固且持续的整合开发:基于每项任务的构建过程
- 牛X的核心开发人员:这些家伙可以帮助提高代码库的质量并完善体系结构。
- 代码质量的重要性:团队以及整个公司都知道保持一个高质量的代码库的价值。
- 不断的自组织:整个团队愿意定期评估并矫正调整他们的开发过程
结对编程的乐趣
接下来谈一下结对编程。这真的是一次很棒的经历,每个人都应该感受下。你可以找到其他赞美结对编程实践效果的文章,但请让我在这简单的总结一下。
搭档间似乎有一条高速交流通道,我们可以利用这点带给团队很多好处。你可以给菜鸟开发人员搭配个大神以此来培训他。因为核心开发人员可以在团队中快速传播最佳的实践经验和技术知识。这样,新的工具与技术自然而然就可以在团队中得到分享,每个人都会进步。
两个人结对编程可以共同分担每天的工作的压力和精力。有时这些状态的起伏都是相互的。当一个人工作正劲而另一个分神时,状态好的可以帮助另一个集中注意力。而当两个人同时注意力高度集中时,那这工作效率是要逆天的节奏啊,他们互相可以依靠、信赖。
一个总是一起工作的小伙伴可以促进自我提高;每个人都想在他们尊重的人面前表现出色。而且这时我们往往更容易做出些策略决定,同时也会带来更好的工作气氛:两个人都不会轻易的选择捷径,经常会就某个问题进行权衡讨论。
代码集体所有权这个概念更容易被接受,因为代码都是至少两人合作完成的。这些使得整个团队能以更积极的心态面对失败。
结对编程是团队平衡的指向标
当一切都很顺利的时候,结对编程看上去是那么的美好,但它同时也是只不羁的野兽需要去掌控。结对编程的效率可以充分反映团队的平衡。结对编程对训练菜鸟来说是非常好的一个方法,但是过分的稀释核心人才,将他们分配给所有的初级开发人员会破坏团队的生产力和氛围。当一个团队有过多的初级开发员,这种现象会发生的更快,结对编程就变成了场人才调配的俄罗斯方块游戏。
同样的平衡问题也会影响到知识库。结对编程对于改进、重构之前的知识库非常有效。一但一个新的库或者分支被建立起来,就会增加结对人员分配和轮换的难度。
团队需要不停的发现类似问题并尽早加以改正。知识和人才的失衡会导致团队效率降低,更有可能破坏项目进程。
结对编程文化会滋生单一文化
结对编程是个较为高强度的实践方法,它并不适合每个开发人员。这就意味着一个团队要想采用结对编程,就必须招募那些在项目中热爱与人交流的开发人员。团队必须权衡其中的利弊,这样才能达到结对编程的效果。
招募队员的评价标准也层出不穷。每个开发人员都应该问问自己,“我是否愿意每天坐在别人旁边和他一起编程、工作?”。这些问题对建设一个和谐团队是非常重要的,但同时这些问题也会引起队员间浅意识的恐惧与偏见。千万别雇佣和团队成员性格、背景截然不同的开发人员,他很有可能会破坏团队气氛。
结对编程会帮助团队根据自身的利益构建统一的开发环境(包括开发工具、实践方法、开发技术),但它也会让团队在开发的道路上一意孤行。促进技术产业的多样性一直是项艰巨的任务,而结对编程文化更容易同化整个团队。
结对编程不适于解决Hammock问题
结对编程有益于项目持续发展和某些技术知识的共享,但结对编程不利于做出谨慎的决定以及创造力的发挥。只有在处理更大的系统架构设计问题,我们才能做出这类谨慎的决定。
特别当大神与菜鸟配对时,大神会在编程前先做程序设计而不是把时间“浪费在”与菜鸟的交流上。这就会导致在程序设计中1+1<2。
有时候你需要代码审查
当一个使用结对编程的团队经历了上述种种问题,核心开发人员便会开始怀疑搭档们的业务能力。也许指不定在哪个配对小组中,两个开发人员都是菜鸟。渐渐的团队间的信任就会出现危机,这就意味着核心开发人员会觉得应该进行代码审核。因此这种团队间的信任危机会严重影响到结对编程的效果。
代码审查的乐趣
起初,我觉得我会很不适应代码审查文化,因为我已经习惯了结对编程文化。但事实却相反,刚开始的体验让我觉得如鱼得水。
在代码审查中,没人会看到你还未完全满意的代码。因为开发人员知道自己编写的代码最终都会被别人阅读,所以保持好的编程风格的压力激励着开发人员。
与结对编程相比,代码审查允许开发人员可以对问题进行深入思考。你可以花上一小时在房间内独自思考、出去溜达寻找灵感、google下相关问题的背景信息、阅读相关学术论文或者做些其他的事情。这种自由度可以让开发人员找到更多解决问题的方法,有利于整个代码构建的过程。
在一个使用代码审查的团队中,你写的代码就代表自己,因为你与同事们沟通的主要渠道就是你写的代码。这让团队能包容更多个性迥异的开发人员,在招募队员时更有效率。你会很愿意与一位难以相处但代码写的非常好的开发人员共事。
代码审查是异步的,这就带来了很多好处。首先,团队更容易为队员们灵活地调整工作时间表。如果一个开放人员从早上5点到中午的工作状态很好,那再好不过。如果另一个开发人员要去夜校学习,更倾向加班,这种情况也没有问题。你也可以有策略的分配代码审查任务,确保更多有经验的开发者加入到代码审查的过程中。这样无形中提高了代码的质量,避免项目中的漏洞。
我还发现使用代码审查更能促使你对自己提的意见的价值进行思考。在结对编程的过程中,出于个人喜好或是强迫症,你会忽略很多代码细节。但在代码审查的过程中,你必须判断你推荐给别人修改代码的意见是不是合理、可靠。我自己也有些坚持(放弃)建议的经历。我希望未来我能在这部分记录我更多的感受。
代码审查让你变得孤单
结对编程文化与代码审查文化最明显的差别就是每天你总是一个人构建代码。对某些个性的人来说,这再好不过。但对我来说,这是个难以适应的转变。
当然,有许多方式可以避免孤单带给你的困扰。比如,和其他岗位的同事们呆在一起。我已经经历了两种截然不同的社交方式,想去了解 37 signals 的《remote work》这本书里面的论断,也许它能给出如何处理不同社交方式的答案。
隐私 vs 自控
虽然你有在同事面前好好表现的动力,但你是唯一清楚每天你在干嘛的人。你可以出去溜达一圈寻找解决问题的完美方法,但你也可以到处闲逛、与别人闲聊、不做正经事。
与结对编程相反,代码审查对项目进度没有严格规定。一个开发人员在固定的时间内没有必须要完成任务的压力。任务的进度完全于自己控制。这可能会造成严重的后果。
堆积起来的代码审查任务
虽然由于代码审查的异步性,它具有更灵活的项目进度安排时刻表,但在某些情况下它也会遇到执行的瓶颈,比如每个任务都需要审查,或是核心开发人员由于代码审查的任务繁多而无法进行自己的编程开发。
在代码审查中,开发人员间的交流慢且有局限性 —– 在别人编程时提出建议的速度远远比审核已经完成的代码快。这种速度上的差距可以通过立刻审查已完成的代码的方法有所减少。而且缺乏经验的开发人员常常会落入一些代码审查的陷阱中。
“嗯,好像适合我”
总之,结对编程促进开发人员在构建过程中交流,而代码审查通常在任务构建完成后进行,这有利于项目的整合。代码审查需要审阅者投入相当多的精力,这就会使审阅者对代码质量的要求相对宽松。
哪个更好?
我希望我已经阐述了结对编程和代码审查在保持代码质量的实践中的利与弊。最后也是最重要的是团队对所做的选择要采取务实做法,因为这会让团队能坦诚的面对执行效果。一旦你意识到你使用方法的不足,你才能对此做出改进。
如果你还未解决上述的这些问题,那就加入一个注重代码质量和项目进度的团队,在团队中试着去寻找这些问题的解决方案吧。