结对编程最常见的失败形态是两个人坐在一起,一个写代码,另一个看手机。名义上在结对,实际上是一个人写代码加一个观众,成本翻倍,收益接近零。结对要有效,需要角色分工是真实的,而不是两个人轮流打字。
驾驶与导航
两个角色有明确的分界:
- 驾驶者(driver):操作键盘鼠标,负责把想法落实成代码,处理语法、命名、编辑器操作这些细节。
- 导航者(navigator):不碰键盘,负责观察全局——当前写法是否符合目标、下一步该做什么、有没有偏离方向、有没有遗漏的边界情况。
分工的价值在于认知负载的分离。驾驶者处在”如何实现”的层面,容易陷入细节;导航者处在”要达成什么”的层面,能持续对照目标。一个人同时做这两件事时,通常会在细节里待很久才发现方向偏了。
导航者要克制”抢键盘”的冲动。看到驾驶者写出一个自己不认可的写法,正确做法是先记下来,在当前这一步完成后讨论,而不是马上接手改掉。频繁打断会让驾驶者失去连续性,结对的效率反而低于单人。
导航者的职责是预判
导航者如果只是”看着屏幕等对方写完”,价值很低。真正的职责是提前一步:
- 驾驶者开始写一个循环,导航者应该已经在想边界:空输入、只有一个元素、超大输入。
- 驾驶者在改一个函数,导航者应该在想调用方:有几处调用、哪些测试会受影响、错误信息是否还准确。
- 驾驶者卡住了,导航者应该能提出两个可能的方向,而不是一起沉默。
预判需要导航者掌握足够上下文。如果导航者对这块代码完全陌生,结对就退化成”边看边学”,这时应该先花十分钟让驾驶者讲清楚背景,或者直接换成讲解模式。
具体做法:导航者手边放一张便签(或一份临时文档),记录”待讨论”和”待处理”两类事项——不打断当前思路,也不让发现的问题被遗忘。这张清单在轮换时交接,是轮换能无缝进行的关键。
轮换节奏
轮换的目的是让两个人都保持参与,同时避免某一个人长期占据驾驶位。经验上 25 到 40 分钟一轮比较合适:太短会打断心流,太长会让导航者失去注意力。
轮换时的交接要说三件事:当前做到哪一步、接下来打算做什么、待处理清单里有什么。这个过程通常需要两三分钟,是必要的成本。
轮换还有一层作用:它强迫知识双向流动。如果一直是同一个人驾驶,另一个人只会在旁边看,学到的东西有限。轮换之后,两个人都要亲手实现,理解深度完全不同。
有些情况不适合机械轮换:驾驶者正在一个复杂实现的中间状态,强行交接会让两个人都失去上下文。这时可以约定”完成这一步再换”。
什么时候值得结对
| 场景 | 结对的收益 | 备注 |
|---|---|---|
| 复杂业务逻辑(状态机、计费规则) | 高:边界情况被双重检查 | 缺陷最集中的地方 |
| 疑难 bug 排查 | 高:假设被即时挑战 | 一人容易陷入单一假设 |
| 知识传递(新人接手陌生模块) | 高:上下文直接转移 | 比文档更快,但要配合文档 |
| 关键设计决策的落地 | 中高:方案在实现中即时验证 | 设计文档先行效果更好 |
| 生产环境操作 | 高:双人复核防误操作 | 已有变更流程的可沿用 |
| 机械性任务(批量改字段名、写样板代码) | 低 | 单人做更快,事后评审即可 |
| 探索性尝试(不知道该怎么做) | 视情况 | 各自先摸索反而更高效 |
判断标准可以简化成一句:这个任务的错误代价高不高,以及思路是否需要被即时挑战。两个答案都是”是”,就值得结对。
远程结对的额外成本
远程结对不是把线下结对搬到屏幕上,它有几个特有的损耗:
延迟。共享编辑或屏幕共享的延迟会让”我想改这一行”变成一段等待。语音与画面不同步时,两个人会互相打断。缓解办法:优先用支持多人同时编辑的工具(而不是单向屏幕共享),减少”你点一下那里”这种需要对方操作的沟通;约定简单的口头协议,比如”我说完这段你再讲”。
共享屏幕的认知负担。只能看到对方屏幕时,导航者无法自己跳转去看调用方或测试,思考被限制在对方展示的范围里。这个问题在”双方各自打开同一份代码、用实时协作编辑同步光标”时会好很多——导航者可以自由查看其他文件,需要对方看的时候再同步位置。
缺少白板。线下随手画个图就能说清的状态机,远程需要额外工具。低成本方案是提前准备一个共享文档或在线画板链接,结对开始时打开;对于纯结构问题,用 ASCII 草图写在代码注释里也够用。
时长上限。远程结对的疲劳度高于线下,连续两小时以上效率会明显下降。经验上把一次远程结对控制在 60 到 90 分钟,中间留出休息,比硬撑一个下午有效。
异步协作的补充
结对解决不了所有协作问题,尤其跨时区团队。异步手段能覆盖一部分:
- 录屏。五到十分钟的屏幕录制加语音解说,适合讲解一段流程或一次排查过程。比写文档快,比开会省时间,而且可以反复看。注意控制时长,超过十分钟观看率会明显下降。
- 设计文档先行。结对之前先有一份简短的设计说明(背景、方案、备选方案、取舍理由),结对时就有共同参照,不用从头对齐。文档不必长,一页足够。
- 决策留痕。讨论的结论要落到可检索的地方——PR 描述、设计文档、提交信息。口头讨论三个月后无人记得,也无法被后人质疑或沿用。
- 草稿 PR。早开一个 draft PR,把思路和未完成的代码放上去,让对方在自己方便的时候异步评论。这比约时间开会轻量得多。
异步与同步不是替代关系:异步适合传递信息和收集意见,同步适合产生新想法和快速消除误解。
如何衡量结对是否有效
用代码行数衡量结对是最糟的做法:结对的产出本来就慢,而它的价值在于少返工、少缺陷、知识分散。
可以观察的几个信号:
- 返工率:结对产出的代码,在评审和后续修改中被推翻的比例是否更低。
- 缺陷密度:结对完成的模块,上线后的缺陷数是否更少。这个数据滞后,但最有说服力。
- 知识分布:模块是否还有”只有一个人能改”的情况。可以用”最近三个月有多少人在这个模块提交过代码”来近似。
- ** onboarding 时间**:新人通过结对接手模块,到能独立完成任务的时间是否缩短。
- 主观感受:结束后两个人是否都觉得思路更清楚了。如果一方长期觉得”还不如我自己写”,说明分工或场景选择有问题。
一个需要警惕的副作用:结对会掩盖流程问题。如果两个人在反复处理本该由工具或规范解决的事情(手工跑重复步骤、等很久的构建),结对只是让这段时间不那么难熬,问题本身没被解决。定期回顾结对的产出,判断该优化的是协作方式还是工程环境。
评论(2)
看完顺手把代码里的魔法数字换成常量了,强迫症舒服了。
已经按这个改完了,同事说像换了个系统。
请 登录 后参与评论。