结对编程指南:方法、优势、挑战与实践建议

📅 2026/6/26 5:37:00
结对编程指南:方法、优势、挑战与实践建议
结对编程Pair Programming是一种由两名开发者共同完成同一项开发任务的软件工程实践。它不仅能提升代码质量还能促进知识共享、团队协作和新成员入职。本文将系统介绍结对编程是什么、如何开展结对编程、常见模式、优势、挑战以及团队在实际落地时可以采用的实践建议。如今许多软件开发从业者都听说过结对编程但它在行业中的普及程度依然参差不齐。原因之一在于结对编程的收益往往不会立刻显现而是在中长期的团队协作和软件演进中逐渐释放。另一个原因是它并不只是“两个人共用一台电脑”那么简单如果没有掌握正确的方法很多人初次尝试时一旦感到不适便很容易放弃。然而根据我们的经验结对编程对团队协作和高质量软件开发都至关重要。从一开始我和贝蒂·斯奈德就是搭档。我相信最好的程序和设计都是由两个人合作完成的因为你们可以互相批评发现彼此的错误并借鉴对方最好的想法。——让·巴蒂克最早的程序员之一所有生产代码都应该由两个人坐在同一台机器前共同编写。——肯特·贝克让·巴蒂克是早期计算机项目女性团队成员之一她们被许多人视为最早的程序员。当时“程序”这一概念尚未完全成形也没有榜样或书籍告诉她们该如何编程但她们已经开始着手编程工作并选择了结对协作。大约 50 年后结对编程才成为一个广为流传的概念。直到 20 世纪 90 年代末肯特·贝克在《极限编程》一书中系统阐述了这一实践。正是这本书将敏捷软件开发实践介绍给了更广泛的读者而结对编程正是其中之一。结对编程本质上是指两个人共用一台机器编写代码。这是一种高度协作的工作方式需要大量沟通。两位开发者在共同完成一项任务时不仅会编写代码还会一起规划、讨论和调整工作内容。他们会不断澄清思路探索不同方案并最终找到更优的解决路径。本文第一部分“如何开展结对编程”概述了几种实用的结对方式适合想要开始结对编程或希望提升结对编程能力的读者。第二部分和第三部分“结对编程的优势”与“结对编程的挑战”将深入探讨结对编程的目标以及如何应对那些可能阻碍目标达成的问题。如果你想更好地理解为什么结对编程对软件质量和团队协作有益或者想获得一些改进建议这两部分会很有帮助。第四部分和第五部分“结对还是不结对”和“说到底为什么要这样做”将总结我们对结对编程在团队流程和协作大局中所扮演角色的看法。如何开展结对编程常见结对编程模式驾驶员与导航员“驾驶员”和“导航员”是经典的结对编程角色划分也可以灵活应用到许多结对编程方法中。驾驶员是坐在“方向盘”后的人也就是操作键盘的人。TA 专注于完成当前的小目标暂时不去处理更宏观的问题。驾驶员在操作过程中应尽量边做边说让搭档了解自己的思路。导航员则处于观察者的位置在驾驶员编写代码时持续审视代码提供指导并分享想法。导航员还会关注更大的问题、潜在漏洞以及后续可能需要处理的事项或障碍。这种角色划分的目的是让驾驶员和导航员从不同角度审视代码。驾驶员的思维更偏向战术层面关注细节和眼前的代码导航员则可以从战略层面观察把握整体方向。常见流程如下首先设定一个相对明确的任务。每次只设定一个小目标。这个目标可以通过单元测试、提交信息或写在便签上的方式来定义。定期轮换键盘和角色。积极参与的互动可以保持学习热情也能帮助双方更好地理解和掌握知识。作为导航员要避免陷入“战术”思维把具体编码细节留给驾驶员。你的任务是退后一步用中期视角补充搭档的战术思维。可以把下一步计划、潜在障碍和想法记录在便签上等小目标完成后再讨论以免打断驾驶员的思路。乒乓式结对这种方法结合了测试驱动开发TDD非常适合边界清晰、可以通过测试驱动实现的任务。“Ping”开发者 A 编写一个失败的测试。“Pong”开发者 B 编写实现代码让测试通过。随后开发者 B 开始下一个“Ping”也就是编写下一个失败的测试。每次“Pong”完成后可以一起重构代码然后再进入下一个失败测试。这样就遵循了“红—绿—重构”的流程先编写一个失败测试红再用最少的必要代码让它通过绿最后进行重构。强风格结对这种方法对于知识传递尤其有用。相关实践者曾对它进行过更详细的介绍。它的规则是“一个想法要从你的脑海进入电脑必须经过别人的手。”在这种模式下导航员通常是经验更丰富的人更熟悉当前环境或任务驾驶员则通常是新手比如不熟悉编程语言、工具、代码库或业务背景。经验丰富的人主要扮演导航员的角色引导新手完成实现。其中一个重要前提是驾驶员要充分信任导航员并且能够接受信息不完整的状态。实现过程结束后再一起讨论“为什么要这样做”以及对方案的疑问。当一方完全是新手时这种方式可以显著提高结对效率。虽然这种方法近似于微观指导但它可以作为一种有效的入职培训工具鼓励新人主动“边做边学”而不是被动“边看边学”。它非常适合初始知识传递但不应过度使用。请记住最终目标是在一段时间后能够自然切换角色并逐步退出这种细粒度指导模式。能够做到这一点才意味着知识传递取得了成功。从结对编程到结对开发“结对开发”与其说是一种具体的结对编程技巧不如说是一种结对编程思维。开发一个用户故事或功能通常不仅需要编码还包含许多其他工作。作为结对伙伴你们要共同负责这些工作。为了帮助你进入这种思维下面列出了一些用户故事生命周期中的非编码活动它们同样可以从结对协作中受益。规划我们的目标是什么当你们刚开始合作开发某个功能时不要急于写代码。功能生命周期的早期阶段是避免浪费资源的绝佳机会。在这个阶段双方一起审视问题能够及时发现误解或遗漏的前提从而节省后续大量时间。理解问题。通读问题描述并互相复述自己的理解。与产品负责人澄清所有疑问或潜在误解。如果团队有“就绪定义”Definition of Ready请再次确认启动工作所需的条件和资源是否已经准备齐全。提出解决方案。集思广益探讨解决问题的潜在方案。你们可以一起讨论也可以先分开思考再互相展示各自的想法。这取决于解决方案本身的清晰度也取决于你们各自的思考风格。有些人喜欢独自思考有些人则喜欢边说边想。如果你们中有人对相关领域或技术不太熟悉请花些时间互相介绍必要的背景知识。规划方案。对于你们选择的方案需要采取哪些步骤才能达成目标是否有特定的执行顺序你们将如何测试理想情况下把这些步骤记录下来可以写在共享文档中也可以写在便签上。这有助于跟踪进度也方便在需要他人接手或协助时使用。写下来还有助于记住待办事项——我们常常低估自己会忘记多少事情有时甚至第二天就忘了。如果团队希望把结对过程中产生的目标、需求、评审、排期、开发、测试、发布和知识沉淀串联起来也可以借助 PingCode 这样的智能化研发管理工具让研发流程中的信息更容易被记录、追踪和复用从而减少结对协作中的信息断层。研究与探索当某个功能需要使用双方都不熟悉的技术来实现时通常需要先进行研究和探索。这类工作并不适合简单套用“驾驶员—导航员”或“乒乓式”协作模式。例如两个人盯着同一个屏幕一起浏览搜索结果通常效率并不高。在结对开发思维下可以采用以下方式先列出需要回答的问题清单以便找到合适的解决方案。分工合作。你们可以分别研究不同问题也可以分别尝试寻找同一个问题的答案。可以上网搜索也可以利用公司内部资源或者阅读双方都不熟悉的新概念资料。在事先约定的时间段结束后重新聚到一起讨论并分享各自的发现。文档除了代码之外文档也是需要共同完成的重要工作。你们可以一起思考当前工作是否需要文档。同样根据具体情况和个人偏好你们可以共同撰写文档也可以由一人先写另一人审核和润色。文档编写是一个很好的例子说明两人合作如何相互督促。文档常常被留到最后当它成为完成项目、获得“完成感”之前的最后一道关卡时我们很容易选择忽略它或者草草了事。而两人协作能够让我们正视这些有价值却容易令人厌烦的事情——未来的我们往往会因此感激现在的认真。结对编程中的时间管理除了常见的结对方式还有一些小工具和技巧可以让结对编程更加顺畅。番茄工作法就是其中之一。它是一种时间管理方法把工作分解成若干时间段通常每段 25 分钟并在时间段之间穿插短暂休息。这种方法几乎适用于前面介绍过的所有结对编程方式并能帮助你保持专注。结对编程可能很消耗精力因此设置提醒、定期休息并定期更换键盘会很有帮助。以下是番茄工作法的实际应用示例决定接下来要做什么。设置一个 25 分钟的计时器例如使用番茄钟浏览器扩展或者真的拿一个番茄形状的厨房计时器。在这段时间内不受干扰地工作。计时器响起时暂停工作先进行一次短暂休息比如 5 到 10 分钟。完成 3 到 4 个这样的“番茄钟”后进行一次较长休息比如 15 到 30 分钟。请真正利用短暂休息放松身心、补充能量、喝点水或咖啡、上个厕所或者呼吸一下新鲜空气。避免把这些短暂休息用来处理其他工作比如回复邮件。结对轮换结对轮换是指两位搭档合作一段时间后其中一人离开当前用户故事另一人则邀请新成员加入继续推进工作。留下来的人通常被称为这个用户故事的“锚点”。轮换的原因之一是现实安排。你的搭档可能生病或休假。或者你们其中一人某天远程办公但当前工作需要现场完成例如涉及硬件调试。另一个原因是让工作内容更加多样化。也许你们两人已经合作了一段时间因为相处太久而开始出现“幽闭感”。又或者你们正在处理一些枯燥、耗费精力的工作——轮换可以让其中一人休息一下也让新加入的人带来新的视角和活力。最后结对轮换最常见的原因是避免知识孤岛、增强代码集体所有权并实现更及时的代码审查。结对编程本身已经有助于实现这些目标但轮换可以进一步提高每一行上线代码平均被审阅的人数。关于理想的轮换频率各方意见并不一致。有些人认为每 2 到 3 天轮换一次至关重要因为这样才能充分传播知识并提升质量。然而每次轮换都会带来成本。一方面新加入的人需要时间熟悉工作另一方面轮换者本身也需要承担上下文切换成本。如果没有一个稳定的锚点来保证工作的连续性那么关于问题和解决方案的隐性知识就容易丢失从而导致返工。对于初级开发者来说有时让他们在某个主题上停留更久反而更有益因为这样他们有足够时间深入理解并让新知识沉淀下来。在敏捷团队中“展示与分享”这个说法有不同用法。这里指的是定期举行的开发者例会例如每周一次的开发者聚会用于讨论技术债务、经验教训以及互相介绍重要的新代码等。因此需要权衡轮换的成本和收益。假设你们已经拥有高质量的知识共享机制包括团队“展示与分享”、易读的代码和良好的文档。在这种情况下坚持高频轮换可能只会略微提升集体代码所有权却会带来大量摩擦和额外开销。规划一天结对编程需要一定的时间安排和日程协调。如果你不花时间考虑和安排这些之后很可能会遇到麻烦。每天开始时先一起查看日程安排。与你的结对伙伴商定当天要合作多少小时并看看是否需要预留时间参加会议或处理其他与结对任务无关的事情。如果你们中有人需要独自工作一段时间请务必保证另一人在对方不在时也能继续推进工作。例如不要依赖对方的电脑来编程。如果你白天有会议或其他安排请设置一个容易注意到的提醒尤其是在和结对伙伴一起工作时。如果你们团队默认采用结对编程建议约定固定的“核心编码时间”。这样可以大大简化日程安排。物理环境结对编程意味着你们需要在同一张办公桌前共享物理空间、近距离协作。这与各自拥有独立办公桌截然不同。如此近距离的相处需要彼此尊重并关注对方的需求。因此花些时间为双方找到一个舒适的工作环境是值得的。确保你们都有足够空间必要时清理桌面。桌前是否能放下两把椅子把垃圾桶和背包移开。你们想使用两套键盘还是一套键盘鼠标也是一样一套还是两套这没有绝对规则我们建议根据具体情况尝试最合适的方案。影响因素包括卫生习惯、键盘共享的配合程度以及可用空间大小。你们是否有外接显示器可用一台还是两台如果没有也可以考虑像远程结对一样设置屏幕共享。在这种设置下你们每个人都可以使用自己的笔记本电脑键盘。询问你的搭档是否有任何特殊偏好或需求例如更大的字体、更高的对比度等。如果你的键盘或 IDE 设置比较特殊请先和搭档确认他们是否能适应。也可以看看是否能设置一个简单机制在需要时快速切换回更标准的配置。如果团队能够就默认设置达成一致将会很有帮助。这样你们就不必一次又一次讨论这些细节。远程结对编程你的团队是远程办公还是有成员偶尔在家办公只要双方都有比较稳定的网络连接仍然可以进行远程结对编程。准备工作远程结对需要一个屏幕共享方案它不仅要允许你看到对方的屏幕还要支持控制对方的电脑以便切换键盘。如今许多视频会议工具都支持这一功能。如果你的公司已经购买了商业视频会议工具授权可以先尝试这些工具。此外也有一些开源的远程控制和视频通话工具。对于带宽较低的场景可以尝试通过 SSH 使用终端复用工具或者使用某些主流代码编辑器提供的实时协作扩展。对于远程团队来说结对编程之外的任务、文档、日历和日常沟通同样需要清晰承接。如果团队需要一个更通用的项目协作系统可以使用 Worktile 统一管理任务、项目、文档、IM、目标、日历、甘特图和工时等内容帮助远程成员减少信息分散带来的协作成本。实用建议使用视频。人们经常通过手势和面部表情交流因此在共享屏幕的同时看到结对伙伴的视频会很有帮助。一些视频会议方案自带该功能如果你的工具不支持可以考虑额外开启一次通话以便彼此看到对方。规划和设计。使用协作式在线可视化工具尽量还原用纸笔或白板画草图的体验。改善音频体验。找一个安静的地方佩戴质量较好的耳机最好是带有定向麦克风的耳机。如果确实无法避开噪音“按键说话”功能也能帮上忙。为了减少外界干扰降噪耳机也是很好的选择。应对网络延迟。长时间操作远程计算机尤其是在网络延迟明显时会让人非常疲惫。因此务必定期更换主控机器确保每个人都有机会在自己本地、没有延迟的电脑上工作。网络延迟也会影响滚动浏览文件因为搭档可能难以跟上进度。建议避免在长文件中频繁滚动可以尝试使用键盘快捷键跳转到文件的不同位置或利用代码折叠与展开功能。人的因素如果你的团队并非全员远程而只是有一两位成员远程办公请尽量让远程同事参与办公室里的所有讨论。我们很容易忘记即使只是坐在同一个房间里人们也会无意间共享大量信息。与素未谋面、彼此不熟悉的人远程协作会带来额外挑战。一方面结对编程是远程团队增进了解的好机会另一方面人们也很容易忽略协作中的这一层关系建设。如果确实没有机会见面可以考虑其他增进了解的方式比如尝试远程一起喝咖啡。最后虽然远程结对可能带来一些挑战但它也比现场结对更容易保持专注因为戴着耳机往往更容易排除外界干扰。一起吃甜甜圈共同完成任务后一定要庆祝击掌庆祝听起来也许有些老套但它其实是一种可以共同完成的“能量姿势”能让你精神振奋为下一个任务做好准备。或者你们也可以创造自己的庆祝方式例如用甜甜圈来庆祝职业上的成就。结对编程中应避免的情况不同的方法和技巧可以帮助你获得更好的结对体验。下面是一些常见误区请尽量避免。走神结对编程时请避免阅读邮件或使用手机。这些行为可能会让搭档感到不被尊重也会分散你们对当前任务的注意力。如果确实需要查看某些内容请清楚说明你在做什么以及原因。通过安排充足休息时间并每天预留一些个人时间确保每个人都有足够时间处理邮件等事务。微观管理模式警惕微观管理模式。它不给对方留下思考空间。如果有人不停地给你下达类似下面这样的指令就可能已经进入了这种模式“现在输入System点print……”“现在我们需要创建一个名为……的新类。”“按 Command Shift O……”不耐烦遵循“5 秒规则”当导航员看到驾驶员做错事、想要发表评论时至少先等待 5 秒。驾驶员也许已经意识到了问题如果你立刻出声可能只是在不必要地打断对方思路。作为导航员不要立即指出每一个错误或即将出现的障碍。稍等片刻让驾驶员自行纠正或者先把信息记下来稍后再讨论。如果你立刻介入可能会干扰驾驶员的思考过程。霸占键盘注意不要“霸占键盘”你是否一直控制着键盘不让搭档也有机会输入代码这可能会让双方都感到恼火也会因为搭档缺少“主动参与”而难以集中注意力。试试前面提到的方法确保你们经常轮换键盘。每天结对 8 小时真正致力于结对编程的团队有时会每天结对 8 小时。根据我们的经验这种做法不可持续。首先它会让人精疲力竭。其次在实践中也并不现实因为除了编码之外还有许多其他事情要做例如查看邮件、一对一沟通、参加会议、研究与学习等。因此在规划一天工作时请记住这一点不要期待一天中 100% 的时间都能一起编码。没有所谓“唯一正确”的方法结对编程有很多种方式并不存在所谓“唯一正确”的方法。它取决于你的编程风格、性格、经验、具体情境、任务类型以及其他诸多因素。最终最重要的问题是你是否从中获得了预期收益如果没有那就尝试其他方法反思、讨论并调整直到获得预期效果。结对编程的优势结对编程有什么好处理解它的潜在优势非常重要这能帮助你决定何时进行结对编程、如何做好结对编程以及如何在遇到挑战时激励自己坚持下去。结对编程可以帮助你实现软件质量和团队协作方面的主要目标。那么结对编程究竟如何帮助你实现这些目标呢知识共享让我们先从结对编程最显而易见、也最没有争议的优势说起知识共享。两个人共同编写同一段代码有助于团队在日常工作中交流技术知识和领域知识避免知识孤岛形成。此外当两个人共同理解和讨论问题时找到理想解决方案的概率也会大大提高。不同的经验和视角能够帮助我们考虑更多可能方案。实用建议即使你对相关技术或领域一无所知也不要回避结对编程。如果你一直停留在自己最熟悉的领域就会错过学习新知识的机会也无法把知识传播给团队。如果你发现某个团队成员总是专注于相同主题不妨鼓励他们尝试不同主题以拓展专业能力。此外还可以创建一个技能矩阵列出团队中的技术主题和业务主题以及每个人在各个领域的优势与不足。把矩阵贴在团队区域的墙上大家就可以一起努力让知识分布更加均衡。反思结对编程迫使我们讨论方法和解决方案而不是只在脑海中思考。把想法说出来并解释清楚能促使我们反思自己是否真正理解了问题或者是否真的找到了好的解决方案。这不仅适用于代码和技术设计也适用于用户故事及其所带来的价值。实用建议结对编程需要彼此信任才能营造一种双方都能自由提问、坦诚表达不理解之处的氛围。因此在结对编程中建立团队内部关系非常重要。务必安排时间进行定期一对一交流和反馈。保持专注两个人一起工作时更容易采用结构化的方法你们都必须明确表达自己为什么要做某件事以及目标是什么。独自工作时人更容易分心。例如你可能会不经思考地“快速”尝试不同方法然后几个小时后才发现自己陷入了无意义的探索。搭档可以防止你陷入这种状态帮助你聚焦于当前任务或用户故事真正关键的部分。你们可以相互提醒保持方向。实用建议一起制定计划。讨论手头任务思考为了达成目标需要采取哪些步骤。把每个步骤写在便签上如果是远程办公可以在工单管理系统中创建子任务。按顺序整理好然后逐一完成。也可以尝试结合番茄工作法争取在一个番茄钟内完成一个目标。永远不要忘记沟通是关键。要坦诚交流你们正在做什么并要求对方解释自己的思路。随时随地进行代码审查当我们结对工作时有四只眼睛同时关注细节和整体这样就能在过程中发现更多错误而不是等工作完成后才发现。重构始终是编码过程的一部分因此也是结对编程的一部分。当身边有人时改进代码会更容易因为你们可以讨论实现方法、命名以及设计选择。事后代码审查存在一些缺点。我们将在后面的“结对还是不结对”部分中更深入地探讨这一点。实用建议互相提问。提问是理解当前工作并找到更好解决方案的最有力工具之一。如果代码对你们中某个人来说难以阅读或理解那就尝试用更容易理解的方式表达。如果你觉得已经结对编写过的代码还需要更多审查不妨反思一下你们是否可以改进结对方式。你是否在结对过程中没有提出所有问题和疑虑为什么会这样你们需要做出哪些改变结合两种思维模式正如前面在描述经典“驾驶员/导航员”模式时提到的结对编程允许你从不同角度审视代码。驾驶员通常处于更“战术”的模式关注细节也就是当前这一行代码。导航员则更具战略视角着眼于整体方向并把后续步骤和想法记录在便签上。一个人能同时兼顾这两种思维模式吗恐怕很难。将战术视角和战略视角结合起来能够提高代码质量因为它既能让你关注细节又能让你把握全局。实用建议记得定期轮换键盘从而切换角色。这有助于你放松身心避免厌倦并练习两种不同的思维方式。作为导航员要避免陷入“战术”思维把具体编码细节留给驾驶员。你的任务是退后一步用中期视角补充搭档的战术模式。集体代码所有权集体代码所有权摒弃了模块个人所有权的概念。代码库归整个团队所有任何人都可以修改任何部分。——马丁·福勒结对编程确保每一行代码至少被两个人看过。这提高了团队中任何成员都能放心修改代码的可能性。与单人编程相比结对编程还能让代码库更加一致。实用建议单靠结对编程并不能保证实现代码的集体所有权。你还需要确保成员会轮换到不同的搭档和代码区域以防止知识孤岛形成。降低团队在制品数量限制在制品数量是看板的核心原则之一旨在提升团队协作效率。设定在制品数量上限有助于团队专注于最重要的任务。如果团队设置了在制品数量限制整体生产力通常会提高因为多任务处理不仅会降低个人效率也会降低团队效率。尤其是在大型团队中结对编程可以限制团队并行处理的任务数量从而提高整体专注度。这有助于确保工作持续推进并及时解决遇到的障碍。实用建议将团队在制品数量限制在团队中可形成的开发者结对数量之内并在团队空间中公开展示如果远程办公则可以在在线项目管理工具中展示。在接受新任务之前请务必留意这一限制。在制品数量限制所带来的约束可能会自然推动你们养成结对编程的习惯。快速完成新成员入职由于结对编程有利于知识共享因此可以帮助新团队成员快速融入团队。新成员可以在搭档帮助下了解项目、业务和组织。团队人员变动会影响团队运作人们也需要时间彼此熟悉。结对编程可以最大限度减少这种影响因为它迫使人们进行比单独工作时更多的沟通。实用建议仅仅把新员工安排进结对编程然后期待他们“神奇地”融入团队并完成入职是不够的。务必在他们第一次结对编程之前向他们介绍整体框架和更广泛的背景信息并预留额外的入职时间。这能让他们更容易跟上进度并在结对过程中做出贡献从而获得最大收益。结对编程时请尽量使用新成员自己的电脑以确保他们之后也能独立完成编程工作。制定一份包含待讲主题的入职计划。对于某些主题可以安排专门培训对于其他主题新团队成员可以带着这份计划在结对编程中学习。如果某个主题已经在结对过程中讲解过就可以在清单中勾选。这样团队中的每个人都能清楚看到入职进度。结对编程的挑战结对编程虽然有很多好处但也需要练习而且一开始未必顺利。下面列出了一些团队常遇到的挑战以及相应的应对建议。遇到这些挑战时请牢记结对编程的好处并记住你为什么要进行结对编程。明确你希望通过这一实践达成什么目标非常重要只有这样你才能据此调整实践方式。结对可能令人疲惫独自工作时你可以随时休息需要时也可以让思绪放松片刻。而结对工作会迫使你长时间保持专注并寻找与对方节奏和思维方式的共同点。专注力的提升是结对工作的优势之一但它也可能让结对过程变得紧张而疲惫。应对方法充足休息是应对这一挑战的关键。如果你发现自己经常忘记定期休息可以尝试设置闹钟例如每小时休息 10 分钟。也可以使用番茄工作法等时间管理技巧。不要错过午休时间离开电脑屏幕好好休息。无论是否结对编程休息都至关重要而且能够提高工作效率。防止疲劳的另一个重要方法是不要每天结对 8 小时最好将结对时间限制在每天最多 6 小时。定期轮换驾驶员和导航员角色也有助于保持精力。密切合作可能很困难长时间与他人密切合作会带来压力。你需要持续沟通而这需要同理心和人际交往能力。你们在技巧、知识、技能、性格、外向程度或解决问题方式上可能存在差异。某些组合可能不太契合导致合作初期并不顺畅。在这种情况下你们需要投入一些时间改善合作让它成为一次互惠互利的学习经历而不是一场争执。应对方法在结对编程开始前进行一次简短对话可以帮助你们了解彼此的风格差异并制定相应的调整方式。第一次结对可以从这样的问题开始“我们希望如何合作”“你更喜欢哪种结对方式”了解自己的工作方式和高效状态固然重要但也不要排斥其他方法——你也许会发现一些新的可能。一天的结对结束后可以互相进行一轮反馈。如果你觉得给对方反馈很困难不妨把它看作一次小型回顾。反思你们在结对过程中的感受你们是否保持专注是否感到疲惫哪些方面让你们觉得舒适哪些方面让你们不适你们是否经常轮换键盘是否达成了目标下次有没有什么想尝试的做法最好尽早养成这种习惯这样当问题出现时你们已经熟悉如何给出反馈。有许多优秀的培训课程和书籍可以帮助你处理人际冲突和困难例如如何进行艰难对话。团队应当共同面对挑战而不是把冲突留给个人解决。例如你可以组织一次关于结对编程的研讨会讨论如何共同应对困难。研讨会开始时先收集大家眼中结对编程的益处以便了解彼此的期待。随后收集每个人在结对编程中遇到的挑战。接下来团队可以一起思考哪些措施有助于改进。你还可以收集团队成员的敏感点在结对编程中什么事情会让你立刻感到不舒服会议打断工作你是否经历过连续几天开会却感觉什么也没完成这种情况几乎每个交付团队都会遇到。会议对于讨论、计划和确定开发任务固然必要但另一方面它们也会打断工作流。当团队采用结对编程时过多会议会造成更严重的后果。如果每位结对成员的会议时间各不相同干扰就会成倍增加。应对方法一种方法是限制会议发生的时间段。例如定义核心结对时间在这个时间段内不安排会议或者制定类似“中午以后不再开会”的规则为非会议工作留出完整时间。此外也值得审视会议时长和会议总数。你们真正需要哪些会议这些会议的目标是什么如何提高会议质量例如通过充分准备、有效引导和清晰议程但有一点可以肯定会议总会存在。那么如何在结对编程中应对它们在结对开始前一起查看日程安排确保有足够时间开始工作。如果有会议可以考虑结对参加。也可以依靠产品负责人或其他非结对成员帮助团队在核心结对时间段内减少干扰。技能水平不同当两个经验水平不同的人围绕某个主题合作时往往会导致对彼此贡献程度的错误假设或者因节奏不同而产生挫败感。应对方法如果你的搭档在这个领域更有经验不要想当然地认为他们一定最了解情况。也许在解释做事方式的原因时他们也会获得新的启发。询问“如何做”和“为什么这样做”可以引发富有成效的讨论并找到更好的解决方案。如果你的搭档在这个领域经验较少也不要以为他们无法为解决方案做出贡献。你可能正受限于自己的惯性思维而不同视角或许能帮助你找到更好的方案。此外记住解释一个概念本身就是绝佳机会可以检验你是否真正理解并深入思考过它。了解不同学习阶段有助于理解人们从新手到专家的成长过程。相关实践者在一次关于高效团队模式的演讲中对这一点做过精彩阐述。他引入了德雷福斯技能习得模型用以理解不同学习阶段以及这些阶段在结对学习背景下如何组合。权力关系处理权力关系可能是这份清单中最困难的挑战之一。结对编程不可能发生在完全没有层级结构的环境中。这种层级结构既可能是正式的例如经理与下属之间的关系也可能是非正式的。非正式层级结构包括但不限于初级开发者与资深开发者。非男性与男性。职业转型者与计算机科学专业背景者。有色人种与白人。以上只是部分例子。权力关系是流动且相互交织的。当两个人建立关系时多种权力关系可能同时发挥作用并相互重叠。为了更好理解权力失衡如何影响结对关系下面列出一些示例在结对编程中一个人霸占键盘不给搭档留下空间完全主导了编程过程。一个人始终保持教学姿态和教学语气。一方不听另一方意见并轻易否定对方建议。有时将这些情况与层级结构联系起来并不容易你可能只会觉得彼此“不合拍”。但问题根源往往在于双方之间的不平衡。有实践者曾围绕这一主题进行过系统分享并更广泛地探讨了敏捷开发中的权力关系。应对方法解决这一问题的第一步是处于权力优势一方的人承认并正视自己的位置。只有这样你才能诚实反思自己与搭档的互动以及权力关系如何影响这些互动。试着思考自己的立场和处境你可以采取哪些积极措施来减少权力失衡认识这些差异并调整自身行为以改善协作并不容易。这需要大量自我反思。一些培训可以帮助个人或团队做到这一点例如反偏见培训或盟友技能培训。在大量未知中结对当你们共同研究一个庞大课题而双方都不知道如何解决问题时传统结对编程模式往往不再奏效。例如你们第一次使用某项技术或者尝试一种新的方法或模式。在某些情况下共同研究和实验确实有效但有时也会令人沮丧因为每个人理解事物运行机制的方式不同阅读和学习速度也不同。应对方法当存在大量未知因素时例如你正在使用一项新技术不妨先进行一次探索性验证Spike在正式开始实现之前先了解相关主题和技术。别忘了与团队分享你的发现可以组织一次知识交流会绘制一些图表并发布到团队空间中。在这种情况下请记住采用结对开发思维而不是狭义的结对编程。分开研究是可以的前提是你们先商定好需要共同回答的问题。没有独处时间前面我们提到持续不断的交流非常消耗精力。大多数人一天中也需要一些独处时间对于性格内向的人来说尤其如此。独自工作时我们通常会自然地抽出时间深入研究某个主题或在需要时进行学习。但在结对编程中这可能会感觉像是对工作流的打断。那么如何在需要时抽出时间独自学习呢应对方法再次强调不要每天结对 8 小时。和团队商定核心编码时间并将结对时间控制在每天最多 6 小时。你可能还需要安排几个小时的自主学习时间。当两个人都感觉自己没有足够的共同知识来解决某个问题时可以先分开阅读资料然后分享结果再继续实现。轮换导致上下文切换知识共享是结对编程的优势之一前面也提到轮换可以进一步增强这种优势。但另一方面过多轮换会导致频繁的上下文切换。应对方法在轮换频率与新搭档充分理解用户故事背景、有效做出贡献之间找到平衡。不要为了轮换而轮换而是思考共享特定背景信息是否重要以及为什么重要并给予它足够时间发挥作用。结对需要脆弱性结对编程需要坦诚相待。这意味着分享你知道的一切也分享你不知道的一切。这对我们来说很难。程序员应该很聪明非常非常聪明。大多数人看到我们做的事情都会说“我永远也做不到。”这让我们觉得自己有点特别也给了我们一种自豪感而自豪感会让我们变得刀枪不入。——汤姆·豪利特结对编程时很难坦然承认自己不懂某些东西或者对某个决定并不确定。尤其是在“10 倍工程师”这类神话层出不穷的行业里我们往往会根据彼此使用的编程语言或五年前做出的设计决策来评判对方。脆弱性常常被等同于软弱。在大多数现代文化中展现强大才是常态。但正如研究者布琳·布朗在多次演讲和著作中阐述的那样脆弱性实际上是创新和变革的重要因素。脆弱性是创新、创造力和变革的源泉。——布琳·布朗应对方法展现脆弱需要勇气也需要创造一个让人们感到更安全、更愿意表达脆弱的环境。归根结底这关乎建立彼此信任的团队包括定期一对一沟通、反馈机制以及鼓励提问的文化等。对于团队中拥有更大权威的人来说展现脆弱往往更容易风险也更小。这种权威可能来自个人影响力例如他们本身就备受尊敬也可能来自制度性位置例如他们拥有“技术负责人”这样的头衔。因此这些人率先示范、树立榜样使脆弱性表达成为一种正常行为对于让其他人也能更安全地展现脆弱至关重要。说服经理和同事结对编程倡导者经常很难说服经理或同事将结对编程作为团队日常工作的一部分。应对方法说服别人相信结对编程有效并没有简单秘诀。关键在于先花时间讨论确保每个人对它有一致理解例如共同阅读这篇文章。然后找到尝试的方法可以先从一对结对程序员开始让他们分享经验也可以提出一次团队实验例如“接下来的两个迭代默认采用结对编程”。务必安排反馈和回顾机会分享哪些方面进展顺利哪些方面遇到了困难。归根结底你不能强迫别人接受某种实践而且这种实践也并非对每个人都有效。你最终可能只能和团队中的一部分成员进行结对编程至少初期如此。根据我们的经验让人们接受这种实践的最好方式是让他们经常接触它亲身体验团队成员在结对编程中获得的收益和乐趣。在这种情况下最常被问到的问题是经济效益结对编程是不是只是让成本翻倍它是否真的物有所值因为它能提升质量并带来团队收益确实有一些研究探讨过这个问题其中有些研究经常被引用来证明结对编程的价值。然而我们对试图“科学证明”结对编程有效的做法持谨慎态度。软件开发是一个充满变化和不确定性的过程除了代码行数之外还有许多难以比较和衡量的成果例如分析、测试和质量。坚定反对结对编程的人总能找到方式质疑任何旨在证明开发效率的“科学”实验的可复现性。归根结底你需要证明它对你有效——而唯一方法就是在你自己的环境中进行尝试。结对还是不结对我们的经验清楚表明结对编程是可持续地创建高质量、可维护软件的关键实践。参见前文“结对编程的优势”部分。然而我们也不认为教条地、始终采用结对编程一定有益。结对编程对你究竟有多有效应该采用多少以及适用于哪些任务都可能因人而异。我们发现将结对编程设为团队的“合理默认”做法很有帮助然后在需要例外时再进行讨论。下面来看几个例子在这些情境中平衡结对的方式和时机很有帮助。枯燥乏味的任务有些编码任务很“枯燥”例如它们只是按照定义明确的样板方法完成一些重复工作。那么也许不需要结对编程如果整个团队都熟悉这种方法或者这种方法很容易掌握知识共享似乎就没那么重要。并且由于这种成熟模式过去已经成功应用实时审查的作用似乎也更小。所以是的也许你确实不需要结对编程。然而请务必记住重复性工作可能是糟糕设计的信号。结对编程可以帮助你找到处理枯燥代码的合适抽象方式。此外当你的大脑进入“这很简单”的自动模式时也更容易遗漏关键信息或犯粗心错误。“我真的可以独自完成这件事吗”对于刚入门的程序员来说结对编程有很多好处因为它提供了一个相对快速地向经验丰富团队成员学习的机会。然而初级程序员在结对编程时也可能会怀疑自己的能力“我真的能独立完成吗”他们也可能因此错过学习如何独立解决问题的机会。我们都会经历挫折也都会在调试和错误分析过程中进行一些无人指导的尝试而这些最终都会让我们成为更优秀的程序员。亲身经历问题往往比别人提前告诉我们会遇到什么问题更有效。有几种方法可以应对这种情况。一种方法是让初级程序员时不时独立工作并安排一位导师定期检查和进行代码审查。另一种方法是让团队中经验较少的程序员彼此结对。他们可以一起寻找解决方案并且比独自编写代码更快摆脱困境。最后如果你是结对中经验更丰富的程序员请确保大部分时间扮演导航员角色。给经验较少的程序员一些空间让他们解决问题。有时候遇到难题需要耐心等待而不是提前指出答案。代码审查 vs. 结对编程结对编程的优势在于它的即时性当审阅者就坐在你旁边时你不可能忽视他或她。——杰夫·阿特伍德许多人认为只要存在代码审查流程就足以作为不进行结对编程的理由。我们并不认同代码审查是结对编程的理想替代方案。首先通常存在一些因素会导致代码审查草率或流于表面。例如当程序员和审查者在没有明确说明的情况下过度依赖彼此程序员可能会推迟一些小决策和改进认为问题会在审查中被发现而审查者则依赖程序员的勤勉信任他们的工作而不再仔细检查代码。另一个因素是沉没成本谬误我们通常不愿意对团队已经投入大量时间完成的成果进行返工。其次代码审查流程可能会打断团队工作流。审查任务需要有人切换上下文。因此代码审查越频繁对审查者的干扰就越大。然而为了确保小变更能够持续集成代码审查又应当频繁进行。这样一来审查者可能成为集成和部署的瓶颈从而增加时间压力而时间压力又会降低审查效果。通过持续集成和持续交付我们希望通过频繁交付小块变更来降低风险。最初这意味着采用主干开发模式。在主干开发模式下延迟代码审查的效果更差因为代码变更无论如何都会立即合并到主分支。因此结对编程和持续集成是相辅相成的实践。我们看到一些团队行之有效的做法是默认结对编程但在必须不结对修改生产代码的特殊情况下使用拉取请求和代码审查。在这种模式下团队应密切监控拉取请求的生命周期确保其不会持续过久从而保证持续集成的有效性。说到底为什么要做结对编程我们讨论了很多结对编程的好处但也花了更多篇幅讨论它的挑战。结对编程需要掌握许多不同技能才能做好甚至可能影响团队中的其他流程。那么为什么还要费这个劲真的值得吗要让团队能够轻松驾驭并成功运用结对编程他们必须培养所有有助于克服挑战的技能专注力、任务组织能力、时间管理能力、沟通能力、给予和接受反馈的能力、同理心以及坦诚面对自身不足的能力。而这些技能对于打造一个高效协作的团队至关重要。结对编程让团队中的每个人都有机会共同提升这些技能。如今多元化被广泛认为是高效团队成功的关键因素之一。多元化的视角、性别、背景和技能已被证明能够提升团队表现但它往往也会首先增加摩擦。它甚至会加剧我们前面讨论过的一些结对编程挑战。例如我们提出的一个关键要素是展现脆弱性而这对于来自弱势群体的团队成员来说尤其困难。请看海外某知名商业评论媒体的一篇文章标题“多元化团队感觉更不自在——而这正是他们表现更佳的原因。”作者指出“同质化团队让人感觉更轻松——但轻松并不利于绩效。……这一观点与许多人的直觉相悖。”为了解释这一点他们提到了一种名为“流畅性启发式”的认知偏差我们更喜欢容易理解的信息并认为它更真实或更美好。这种偏好让我们追求简洁而这在软件开发的许多情境中都非常有效。但我们认为在结对编程中这种偏好并不适用。结对编程一开始会让人感到困难但这并不意味着它对团队不好。更重要的是它并非注定一直如此困难。有实践者曾介绍过自己所在的海外某大型互联网团队如何克服最初引入结对编程等实践时产生的不适感其中提到了反馈文化、非暴力沟通、心理安全感、谦逊以及使命感等因素。结对编程、极限编程以及敏捷软件开发的核心理念都是拥抱变化。敏捷软件实践者认识到变化不可避免因此他们希望为变化做好准备。我们建议团队也应该积极应对并准备好面对摩擦因为在打造高效多元化团队的道路上摩擦同样不可避免。我们所说的积极应对摩擦并不是“制造大量冲突然后我们就会变得更好”。我们的意思是团队应该配备应对摩擦所需的工具并将这些工具纳入日常工具箱而不是只在问题出现时才想起它们。要重视反馈机制改善团队沟通并采取措施营造心理安全的环境。我们认为结对编程常常被人们回避是因为它可能带来摩擦。但我们仍然诚恳地建议你尝试它。如果你把结对编程视为一项可以提升的技能并努力精进最终你将打造出一支更具韧性的团队。关于结对编程的常见问题结对编程是什么意思结对编程是指两名开发者共同完成同一项开发任务。通常一人负责操作键盘另一人负责观察、思考和提出建议。两人会定期交换角色共同推进代码实现、问题分析和方案设计。结对编程适合所有开发任务吗并不一定。结对编程非常适合复杂功能、关键代码、新成员入职、知识传递和高风险变更。对于一些非常简单、重复性强且团队已经非常熟悉的任务可以根据实际情况决定是否结对。结对编程会不会让成本翻倍表面上看两个人完成同一项任务似乎会增加成本。但在实际团队协作中结对编程可以减少返工、提升代码质量、加快知识传播并降低知识孤岛风险。因此是否“划算”不能只看短期编码人数而要结合长期维护成本和团队协作效率来判断。如何开始实践结对编程可以先从小范围实验开始例如选择一个适合结对的用户故事由两名开发者共同完成。实践过程中要定期轮换角色、安排休息时间并在结束后进行简短回顾。团队可以根据反馈逐步调整结对频率、结对方式和适用场景。