打造卓越开发者体验:核心原则与实用策略

本文深入探讨了构建卓越开发者体验的核心要素,包括缩短周期时间、维护专注度以及降低认知负荷。文章结合作者在Google和LinkedIn的实践经验,提供了关于优化工具、系统和流程以提高开发者效率、效能与幸福感的实用洞见。

我已在“开发者体验”领域工作了20多年,该领域旨在通过改进工具、系统和流程,帮助开发者变得更有效、更高效、更快乐。我深入参与了Google和LinkedIn开发者体验的关键设计,与该领域的研究社区联系紧密,并持续与各大科技公司的开发者体验负责人保持沟通。

我想为你阐明构成卓越开发者体验的基本原则——这是在该领域需要理解的最重要的事情。我将仅概述每个要点,可能会遗漏一些点(因为内容太多),但希望这是对关键要点的良好概述。

基本概念

在设计开发者体验时,你主要试图优化三件事:

  • 周期时间(亦称迭代时间): 开发者产生任何意图到该意图实现之间的时间。
  • 专注度(亦称“心流”): 开发者能够专注于他们正在处理的任务,而不被打断的能力。
  • 认知负荷(亦称所需知识和决策): 开发者为了完成他们正在做的任务而必须知道多少知识,以及为了实现任务他们必须做出多少决策。

让我们更详细地讨论这些要点。

周期时间(亦称迭代时间)

编写软件的过程涉及大大小小的循环,基本上是开发者的意图与其在物理世界中实现结果之间的时间。最小的循环如“我打算写这行代码”,或“我打算运行这个命令行工具并查看输出”。最大的循环如“我打算通过创建一个产品并让人们使用它来解决问题”,或“我们打算以一种需要100人一年的方式来重新设计我们的系统”。

总的来说,加速大循环的方式是加速小循环。如果你只专注于加速大循环,结果的质量往往会受到影响。例如,假设我看到一个团队需要两周才能将任何变更部署到生产环境。如果我直接介入并说“不惜一切代价加快部署速度”,而不说其他任何话,那么团队可能会以损害最终结果质量和软件可维护性的方式偷工减料。

然而,如果我更深入地调查,我会发现有些小循环耗时太长。也许代码审查者需要很长时间才能回复。可能测试运行时间太长,因此开发者每次做小改动都要等太久。可能部署工具太难用,开发者使用困难并回避它。

另一方面,加速较小的迭代总是安全的(只要你发现它们确实存在问题)。例如,假设代码审查耗时太长。通常,在这种情况下你会发现,审查者只是没有足够快地回复。这里的解决方案是更多地关注审查者的响应时间,而不是整体的代码审查时间。例如,你常常会发现,在这种情况下,代码作者提交的PR过大,导致审查者需要花很长时间来审查。

代码审查本质上是质量流程,因此你希望最终结果是高质量的代码。有时,在开发者和审查者之间需要来回五轮,开发者提交变更,审查者要求修改,直到最终结果良好。你希望这五轮都发生。但你希望每一轮都快速发生。如果每一轮都快速发生,你会发现PR审查时间仅与其应有的时长相当,并且开发者和审查者都对流程感到满意。

这适用于软件开发的各个部分。如果你发现人们编写代码需要很长时间,那么值得研究诸如:他们的构建需要多长时间?他们在开发时本地运行测试需要多长时间?他们能多快获得决策所需的信息?

还值得注意的是,每个循环都是某种形式的“观察、决定、行动”循环。如果你致力于改进开发者体验,最好的改进方法之一是让开发者更容易观察事物。在他们需要的时候,将所需的信息直接呈现在他们面前。(永远不要把他们不需要的信息放在他们面前,因为这对认知负荷不利。)例如,当测试失败时,失败信息应清楚地表明问题所在,这样开发者就不必费力去弄清楚如何修复它。当他们创建新项目时,清楚说明他们的选项是什么以及从哪里开始。只需思考:“我如何能做到让开发者永远不必思考,只需看一眼就知道下一步该做什么?”

专注度(亦称“心流”)

软件开发是一项需要长时间深度专注才能成功完成的活动。开发者正在为他们正在处理的事物构建一个非常复杂的思维结构,并利用这个思维结构来做出决策和编写代码。他们不断地思考(或在笔记中写下)“哦,完成这件事后别忘了做那件事”。这种专注状态通常被称为“处于心流状态”。

当开发者被打断得太彻底或太频繁时,这种复杂的思维结构就会消失,当他们返回任务时不得不重新构建。他们有可能忘记脑海中“接下来做这个”的事情,并因此实际上发布了有问题的软件。

我们将这种形式的中断称为“上下文切换”,即开发者的注意力现在主要放在编写代码以外的事情上。当你强制开发者进行上下文切换时,他们可能需要十或十五分钟才能完全重建专注编码时所拥有的思维结构。因此,即使是小中断也可能代价高昂。

具体来说,一次中断持续多长时间会导致上下文切换因人而异。我见过的数据在30秒到2分钟之间。这也取决于中断是什么。如果中断是一个不需要思考的手机通知,你看了30秒并忽略它,这可能不会打断专注度。如果中断是你收到的某个非常复杂的失败警报信息,那么无论阅读它需要多长时间,都可能会打断专注度,因为它需要大量的脑力工作,从而破坏了开发者关于当前任务的思维结构。

根据我的经验,如果中断引起负面情绪反应,干扰性可能更强。对某事感到心烦意乱是如此分散注意力,以至于很难继续专注于你正在做的工作。你会觉得必须对烦心事做点什么,或者至少思考它。如果有人给我发来令人心烦的信息,或者我的某个工具以一种极其令人沮丧的方式运行,即使中断只有5秒钟,也可能打断我的专注度。

如果你从事开发者体验工作并希望改善心流状态,请思考以下问题:

  • 我的工具是否会迫使开发者在进行编码、测试或调试等任务时,从事一些并非这些任务的复杂任务?
  • 我们是否确保开发者有多个小时不受打扰的时间来专注于编码?
  • 我的工具、系统或流程是否做了让开发者非常沮丧以至于打断他们专注度的事情?

这里的另一个关键点是:开发者是否清楚地知道他们所做工作的目的,并且有明确的方向?也就是说,我是否被分配了一个明确的任务,我知道为什么做这个任务,为谁做,以及预期的结果是什么?否则,我自身的困惑会经常打断我的专注度。我将不得不不断询问同事我应该做什么。我会坐在那里思考我的任务,而不是实际去做。另外,我可能无法构建出最好的东西,因为我没有做出良好决策所需的所有数据。

专注度是另一个你希望将清晰信息直接呈现在人们面前的领域,这些信息他们可以用来观察、决定和行动。不要让他们中断工作去寻找他们现在需要的数据。有时,“我去了解一些事情”本身就是开发者的整个任务,在这种情况下,让他们搜索信息不算是中断,只要他们能轻松找到所需内容。但如果他们正在编码,并且只需要知道诸如“这个函数是做什么的”这样的信息,那么这些信息应尽可能快地在他们的编辑器中直接可用。

认知负荷(亦称所需知识和决策)

“认知负荷”是一个我不太喜欢的术语,因为它的含义不明确。就开发者体验而言,我们指的是:

  • 开发者为了执行一项任务必须知道多少?
  • 开发者在执行任务时被迫做出多少决策?

我将分别讨论这些要点。

减少所需知识

很多人认为开发者应该尽可能多地了解他们在做的事情,我同意这一点。然而,通过移除他们完成任务必须知道的事情,开发者的生产力和体验会得到显著改善。当开发者必须用1和0编码时,他们的生产力要低得多。用汇编语言编写比用Java或Python等高级语言编写效率低得多。了解这些语言如何转换为汇编语言会让你成为更好的程序员吗?是的,会。你应该为了完成每个编程任务而必须知道那些吗?不。

这是大多数公司中负责开发者基础设施的团队最容易出问题的领域。他们制作的工具要求开发者必须深入了解该工具才能完成工作。如果开发者为了完成工作只需要与几个这样的工具交互,这还好。但事实是,他们需要与几十甚至上百个这样的工具交互。当然,有时会有更复杂的任务需要开发者深入并真正学习其中一种工具。但理想情况下,每个工具应该足够直观,使得开发者为了成功使用它,完全不需要过多学习。更理想的是,基础设施应该重新设计,使他们根本不需要使用该工具,除非他们真的需要。

减少选择

这是开发者体验中最具争议的方面之一,但在多家公司长期经验后,我可以自信地说:

开发者只需要做出他们需要做出的选择。

一些开发者认为,他们必须被允许对他们的系统做出每一个选择——用什么编程语言编写,用什么包管理器安装依赖,用什么构建工具,如何缩进代码,用什么监控系统,用什么部署系统等等。我理解这一点——我对自己最喜欢什么也有强烈的看法。但大多数时候,像这样的决策实际上只是迫使团队做他们不应该做的工作——这些工作使他们分心,无法专注于他们试图完成的核心任务。

极端来说,想象一下每次你开始对系统进行更改时,你都必须对选择哪种编程语言、从10个做同样事情的库中使用哪个库、使用什么构建工具、与所有人争论用制表符还是空格、决定使用什么代码审查工具,以及通常做出软件工程中涉及的所有其他可能的决策。你将永远一事无成,对吗?真正让开发者最有效、最高效和最快乐的是,能够专注于他们需要做的任务,而不是必须不断做出无数与此无关的决策。

在一家公司里,我甚至会说开发者不应该被允许做出他们不需要做出的决策。这听起来很极端,但实际上,如果做得对,这会带来极佳的开发者体验。

问题是,开发者通常认为他们需要对实际上不需要的事情做出决策,但他们要等到几个月或几年后才能看到其后果(或者他们无法理解决策将如何影响更大的业务)。例如,不应该允许开发者选择世界上任何编程语言来完成他们的任务——这会迫使他们围绕该语言开发一堆新库或基础设施,而不是专注于他们真正需要完成的任务。这对企业也有很多其他糟糕的长期后果,当你只是一个非常喜欢某种语言的个体开发者时,很难看到这些。(这一点我再次理解!我是一个编程语言爱好者,有很多强烈的个人偏好。)

然而,必须非常小心地应用这一原则——开发者必须被允许做出他们需要做出的决策。我观察过很多人编写代码,每个人使用其编辑器和相关工具的方式差异巨大,因为人们的思维方式差异巨大。你不能对人们工作流的某些部分施加太多硬性约束,因为这会极大地损害生产力,而对整个企业没有任何真正的好处。我从未见过公司说“每个人都必须使用这个编辑器”能带来什么好处。我见过的是,“我们将为一个编辑器提供比另一个更多的支持,但我们仍会将所有功能以命令行工具的形式公开,这样你就可以使用任何你想要的。”

你还必须小心的是,如果你的基础设施限制了开发者可以做出的决策,你就需要非常出色地集中维护该基础设施。也就是说,一个中心团队需要持续做出这些决策并对结果负责。如果你说“每个人都必须在他们的Java项目中使用这个构建工具”,那么你最好确保该工具实际上适用于每个人,从现在到未来都能持续有效。有时你需要提供一组有限的选项。例如,如果你只是说“每个人都只能用Java编写一切”,你会发现它不是所有场景的合适语言。

做好这一点的关键是深入了解开发者的需求以及他们工作的系统需求。你需要深入了解他们解决的各类问题,从而知道哪些决策需要做,哪些不需要做。并且你需要能够随着时间的推移适当调整(改变策略),而不是完全开放并允许混乱。

事实上,大多数开发者并不希望对他们的系统做出每一个决策,然后被迫做一大堆定制的低级工作才能开始他们的任务。他们喜欢编程,因为他们可以告诉计算机做某事并让它执行,并且因为他们享受解决有助于用户的问题。让他们专注于实现目标所需的事情,而不是整个软件工程领域中所有其他可能的决策或任务。

我在《推理与选择》中对此有更多论述,包括讨论了这一原则如何使系统更容易推理。这是任何软件系统最重要的方面之一:无需运行就能推理其行为的能力,而“减少选择”的原则有助于实现这一点。

请注意,我以上主要从基础设施层面的选择来讨论这一点,因为如果你是负责开发者体验的中心团队,这通常是影响最大的。但这个原则广泛适用。在一个团队内部,你可以说“这些是我们的代码模式,请不要使用其他模式”(只要这没有限制必要的选择)。在开发工具时,你可以设置合理的默认值,这样人们就不必对工具允许的每一个可能选项做出决定。这个原则可以应用的领域非常多。

开发者体验的挑战

开发者体验的大多数困难方面是人的方面,而非技术方面。其中一些有技术成分,但许多困难更多在于人类如何做决策、适应变化等。主要困难包括:

  • 理解问题: 当前改进开发者体验最重要的工作是什么?我们如何获得足够多对这些问题的理解,从而构建正确的解决方案?
  • 管理变革: 你如何推出新的变更?你如何让人们采用新系统或新行为?你如何应对因变更而感到不满的人?
  • 提供杠杆作用: 你为开发者构建的工具和系统,其使用/采用所需的工作量不应超过它们所节省的工作量。
  • 说“不”: 你无法一下子解决世界上所有问题。你必须能够排定优先级。此外,有时你会收到来自团队的请求,他们非常想要某个实际上会损害公司开发者体验的工具或功能。
  • 让制造痛苦的人承担痛苦: 如果一个团队做了给另一个团队造成困难(“痛苦”)的事情,而制造痛苦的团队自身从未因此感受到任何痛苦,那么痛苦将无限增长。

让我们更详细地讨论这些。

理解问题

这里最重要的是要知道,问题来自用户,解决方案来自系统开发者。你绝不能、绝不能颠倒这种关系,即你的用户告诉你构建什么解决方案你就构建它,而开发者则坐在那里想象实际上没有人告诉你他们拥有的问题。如果你从事开发者体验工作,开发者就是“用户”,而你则是“开发者”。

这可能非常棘手,因为有时你的用户包括高级主管或技术负责人,他们对要你构建什么有强烈的意见。尽管如此,你仍然需要坚持立场,只从他们那里获取问题所在,而你自己则基于从所有不同用户收集的良好数据来设计解决方案。奇怪的是(我见过这种情况发生太多次了),如果你完全按照用户告诉你的方案构建,而不是做好研究然后设计最佳解决方案,你的用户将不会喜欢它。他们最初可能会喜欢,但随着时间的推移,他们会开始讨厌它,或者那位为你“设计”方案的高管离开了,新来的高管不喜欢它。

也很容易想:“嘿,我也是开发者,所以我知道开发者想要什么”,从而完全跳过与用户交流。这行不通,因为开发者的工作方式非常不同,他们的需求也往往与你大不相同。例如,如果你从未与机器学习工程师交谈过,你会震惊地发现这种体验与做前端Web开发有多么不同。

如果你想了解如何从开发者那里收集数据和反馈,我曾在LinkedIn的开发者生产力与幸福框架上做了大量工作,其中提供了一些指导原则。然而,如果你在一家小公司工作,你也可以直接与人交谈。这相当容易。

反馈与投诉

在你构建了某些东西之后,寻求有关系统的数据和反馈非常重要。尽管我们热爱我们所构建的东西,但我们应该始终寻找开发者遇到的问题,以便我们能够解决它们——包括我们刚刚制作的东西的问题!随着时间的推移,这最终会为公司创造出最佳的开发者体验。

这里需要理解的一点是,在开发者体验领域,人们很少会主动发送正面反馈。当开发者工具“正常工作”时,开发者大多不会想到它们。他们专注于他们正在执行的任务,而不是你的工具,而这就应该是常态。然而,如果某个工具或系统让他们难以完成工作,哪怕只是一点点,他们也会非常清楚地意识到这一点。

此外,并非每个开发者都是好的反馈提供者。通常,他们只是对某个工具有了非常沮丧的体验,他们会向你提供一些非常情绪化的反馈,而不会太顾及你的感受。当然,人们不应该那样做,如果你要写反馈,我鼓励你意识到你发送反馈的对象是一个聪明的、意图良好的人,所以请尊重他们。但有时这种情况会发生,你不应该把它当作对你的人身攻击。

当你收到非常尖锐的反馈时,处理的关键是:让用户知道他们的话被听到了。如果你的工具确实存在缺陷,请认同用户!你不必贬低自己或你的工作,只需诚实地说明你所负责的东西的状态。当你愿意说“是的,我同意这不是一个好的体验”时,用户实际上会更加尊重你。这并不意味着你必须立即修复它——你的团队自行设定优先级。只需让人们知道他们的话被听到了,他们的抱怨是有效的,很多噪音就会平息下来。

有时,在你倾听并承认痛苦之后,人们仍然持续表现出恶意,在这种情况下,你应该直接告诉他们这种行为是不可接受的,如果他们继续这样做,就联系他们的经理。不过,只有少数人会这样表现。永远不要将此作为你对反馈的首次回应。

管理变革

在美国长大,我在历史课上学到了改变历史的伟大革命:1776年的美国革命、法国大革命、苏联革命等等。故事听起来像是领导人引发了一场暴力革命,然后世界几乎一夜之间改变了。然而,当你研究许多这些情况中实际发生了什么时,“一夜之间的暴力革命”实际上只是重新建立了一个与前一个政府非常相似(或更糟)的政府,而真正、积极的变革是通过更缓慢的演变随着时间的推移发生的。

我喜欢用的比喻是在海上调转一艘大船。在你使一艘非常大的船真正断裂之前,你只能以一定的速率转弯。船越大,这个转弯速率就越慢。公司或团队与此非常相似。规模越大,它安全地从一个方向“转向”另一个方向的速度就越慢。现在,需要明确的是,我不是说变革必须永远进行。但它们也不是一夜间就能用魔法实现的。

关于如何安全成功地推出变更,有很多需要了解的知识。

变革抗拒

改进开发者体验时,你必须处理的主要因素之一就是我们所说的“变革抗拒”。你对系统所做的任何变更,在推出时都会收到某人的负面反馈。这种情况发生并不是因为变更本身有什么问题,而是因为用户已经习惯了以前的工作方式,他们不喜欢发生改变。他们可能会批评新的用户界面,或者提出一些关于为什么新东西“很烂”的情绪化论点,但通常他们实际上只是对任何变化本身感到不满。这并不是什么不寻常的事情;这是几乎所有人身上都存在的一个因素。人们倾向于对在一定时期内愿意经历的变革量有一定的容忍度,如果你超出那个度,他们就会感到不满。

识别人们的反馈是单纯的变革抗拒还是对有价值事物的真实反馈,这一点很重要。有几种判断方法:

  • 变革抗拒通常持续3到10天。如果你在推出变更后的最初3到10天内收到用户的反馈,并且大量其他用户没有提供同样的反馈,那么值得考虑用户的反应是否只是变革抗拒。
  • 变革抗拒的反馈通常是情绪化的。可能是侮辱性的。可能只是表达一种观点(“新菜单的颜色很丑”)而不是事实(“我运行了新的命令行工具,它比旧的命令行工具慢了10倍。”)。

管理变革时,你要避免的是制造如此多的变革抗拒,以至于引发反抗。反抗基本上看起来像是太多人变得愤怒,以至于去找你的管理层并阻止你的工作。当有疑问时,向更少的人推出更小的变更,并以更慢的速度扩展。随着时间的推移,你会了解到你可以推出多少变更、多快推出。永远、永远不要进行“大爆炸”式的发布,让所有用户一下子经历巨大的变化。

现在,以上所述,绝不能将所有反馈都归因于“变革抗拒”。通常人们确实有合理的反馈。如果很多人向你提供相同的事实性反馈,你看了之后觉得他们的反馈有道理,并且你认为修复它会改进产品,那么这很可能不是变革抗拒。此外,说“这只是变革抗拒”并不意味着你应该完全忽视该反馈。你至少应该承认它,让人们知道他们的话被听到了。这确实意味着你不应该与那个人争论或试图与他们理论,因为他们正处于一种情绪化反应中,你试图用“逻辑”来说服他们摆脱它不会对任何人有所帮助。如果你认为这是变革抗拒,你承认了他们的感受,而他们只是继续与你争吵,有时你应该忽略他们,继续你的工作。如果他们3天后带着更理性的论点回来,那么你就知道这不只是变革抗拒,而且到那时他们可能也变得更有帮助。

渐进式推出

除了渐进式开发和设计,还必须知道如何渐进式地推出变更,以便不是所有用户同时经历所有变更。这基本上包括三个部分:

  • 管理发布,使其干扰尽可能小。这意味着要努力使小变更尽可能不需要用户付出额外工作来采用。
  • 选择好的初始用户群体进行推出,这个群体要足够大以获得有用的反馈,但又不能太大。
  • 了解何时扩展群体以及扩展的速度。

最小干扰意味着:不要破坏用户的系统。不要要求用户做手动工作来采用变更。必要时提供清晰的文档。确保系统提供非常清晰的错误信息,以便开发者在首次尝试失败时知道该怎么做。基本上,设身处地为用户着想,思考:“我有很多事情要做,我每天使用30个工具来完成它。当有新功能或新工具让我使用时,我希望有什么样的体验?”

如何选择初始群体主要取决于谁将提供有用的反馈,以及你需要群体中有多少人才能获得这些反馈。在开发过程中,通常你和你的团队就足够了。然后可能是你的技术负责人、你所在组织的几位资深人士,然后是你们领域之外一个真正希望采用该工具的团队。你希望你的初始用户是真正投入的,而不是被迫使用该系统,因为这将带给你最积极的使用和最好的反馈。然后你可以扩展到更多团队,然后是公司的某个百分比,最后是整个公司。

你能扩展的速度取决于几件事:

  • 你获得的反馈量。如果你从当前群体获得足够的反馈,并且有很多工作要处理这些反馈,那么就不要扩展群体。毕竟,从更多人那里获得相同的反馈有什么价值?此外,推出一个你已知需要大量工作的产品会损害你的信誉。
  • 你为每个新团队必须做多少手动支持或手动引导工作。在你广泛推出之前,需要减少这方面的工作。否则你的团队将被手动工作压垮,无法在工具上取得进展。自动化的时机(或解决导致巨大支持负担的问题)是在你只有少数用户并且知道自己即将向大量用户推出时。
  • 变革的破坏性有多大,或它引起多少变革抗拒。显然,破坏性越大,你就必须越慢地推出它。你必须考虑你让公司其他人承受了多少工作量,以及这会如何影响公司其他人实现自身目标的能力。

推动采用

假设你已经很好地完成了渐进式推出,但你就是无法让人们使用你的新东西。如何解决?

首先,你必须确定你真正理解了问题,并且这个问题是开发者们知晓并真正希望解决的。然后你必须确保解决方案确实解决了那个问题,而没有给开发者带来很多新问题(比如新系统难以使用、经常失败、做事不如旧系统好等)。你必须听取反馈并加以解决。

然而,只有一种解决方案能让整个公司实现100%的采用:

唯一能实现100%采用的方法是让你的工具使用起来零步骤。

这是什么意思?基本上,这意味着不要把一些新的、手动的事情交给开发者去做,而是将功能直接融入他们的工作流程中。不要让他们运行一个工具来检查他们的PR,而是让它在代码审查期间自动发生。不要让他们运行一个工具来格式化代码,而是让IDE在工作流程的适当点自动格式化他们的代码。基本上,你找到开发者自然而然已经在做的事情,然后改进那个体验,而不是让开发者做新的事情。

如果需要一步才能使用,你或许能达到80%的采用率。如果需要两步,能到30%就算幸运了。如果要求开发者阅读一份长长的文档并遵循一系列复杂的说明,那么,现在你明白为什么没人用你的东西了。

你永远不应该从一开始就追求零步骤。要做到这一点需要大量工作,在工具生命周期的初期不值得这样做。在早期,即使工具采用起来比较困难也没关系。反正你只把它提供给小而热情的群体获取初步反馈。你希望先让工具变得正确,然后再将其直接集成到人们的日常生活中。但一旦你确实把它做好了,“零步骤”就是驱动你实现100%采用的口诀。

提供杠杆作用

致力于工具或改进开发者体验的全部意义在于,你为团队/公司节省的努力应该超过你投入创建和维护该工具的努力量。即使你的工具主要专注于提高工作质量而不是工作速度,这一点也成立——想想如果没有你的工具,要达到同样的高质量结果需要多少工作量。(有时答案是“无限”,因为如果没有该工具,不可能获得如此高质量的结果!)

现在,请记住,在软件中,减少维护工作量比减少创建工作量更重要。因此,你不仅要考虑你的工具带来的即时影响(以及构建它的即时成本),还要考虑随着时间的推移它将节省多少工作量(以及维护该工具将花费多少成本)。不同的公司在计算这一点时有不同的“时间范围”——也就是说,如果我现在投入X小时,我将在Z年内为公司节省总计Y小时的努力。Z就是“时间范围”——公司愿意考虑多长时间内的节省。在Google,我们通常将那个时间范围设定为两年,因此任何对开发者生产力的投资都必须在两年内“回本”。

因此,每当你考虑对开发者生产力、质量等进行投资时,你必须考虑开发和维护解决方案需要多少工作,与它将为公司带来的实际价值相比。

人力时间

在这方面最常见的错误之一是通过某些优化来节省机器时间(CPU使用、内存使用和磁盘空间的长期成本),却忘记了你自己节省了多少人力时间。在大多数情况下,一小时的劳动力成本比所涉及的所有机器时间一小时的费用要昂贵数百倍。在Google,我写过的最受欢迎的文档之一本质上就是对这个原则的证明,它表明你必须节省数万小时的机器时间,才能抵得上你投入的几个小时自己的工作量。当然有许多合理的理由需要优化机器时间,但改进开发者体验很少是其中之一。

当你考虑开发者生产力改进的成本和价值时,首先要考虑你会节省多少人力时间。

服务于你的开发者

如果你从事开发者生产力工作,你的口号之一应该是“我们服务于我们的开发者,而不是我们的开发者服务于我们”。太容易推出一个让开发者做的工作比它节省的工作还要多,或者只是让他们做比应该做的更多工作的工具了。该工具可能让他们填写本可以自动化的信息表单。它可能暴露很多开发者必须了解的复杂实现细节,而不是允许开发者只表达他们的意图,让系统想办法去实现。

如果你从事开发者体验工作,让工具以这种方式运行对你来说工作量要大得多。推出一个迫使开发者完成所有工作的东西要容易得多。但这完全违背了我们所做事情的目的——提供杠杆作用。

说“不”

从事开发者体验的团队往往与他们的客户关系密切。他们可能与你在同一个房间或同一栋楼里。如上所述,他们可能包括公司里拥有很大权力的高级领导。此外,你的客户是开发者,他们往往对自己想要什么有非常强烈的意见,有众多复杂的需求,并且承受着为自己项目交付成果的时间压力。

与此相对的是,基于一天中的小时数、设计好解决方案所需的时间、解决问题的人数、解决方案实际上能由多少工程师分担等,投入到开发者体验上的人类工作量是有限的。

因此,当请求来到团队时,必须有一种方式来提供三种回答之一:“好的,我们现在就做”,“我们稍后做”,或者“抱歉,我们不会做这个”。你可以将这些简称为“是”、“现在不行”和“不”。

在很多情况下,你应该能够说“好的,我们现在就做”。在开发者体验领域,确实会出现大量有价值、合理的计划外工作。通常这是对工具或系统的小型、无争议的修复,一两个小时就能处理好。也可能出现需要一两天但能提供立竿见影的杠杆作用、并且不需要等待进入规划流程的事情。

为了能够对少量的即时工作说“是”,你必须在规划过程中为计划外工作留出空间。如果你做了一个分配团队100%时间的季度计划,你将破坏与公司其他部门的关系。你永远不想陷入这样一种境地:你的一个用户来找你说,“你能修复这个拼写错误吗?”而你必须回答,“请提交一个请求,我们会把它纳入我们的规划流程,并在三个月内考虑。”

不过要记住,任何团队确实有处理即时工作的有限能力。团队中的开发人员需要了解他们实际上能对多少即时工作说“是”,以及何时应改为回答“现在不行”或“不”。

现在不行

对于需要超过几小时或几天的工作、需要进行需求调研、可能有争议、推出困难等,必须有某种流程来接收客户请求并确定其优先级以供深入工作。开发者体验团队及其管理者绝不能对每一个请求都说“是”。如果你这样做,结果就是你永远无法交付任何具有巨大价值和高品质的东西,因为你总是四处奔波扑灭眼前的大火,交付半成品解决方案,然后再与半成品解决方案引发的新的问题作斗争。

关于优先级排序有很多要了解的,但它应基于你对问题的理解、解决方案将提供的杠杆作用大小,以及创建和维护解决方案所需的总工作量。

这里最棘手的一点是,开发者体验团队的工程师通常是接收这些请求的“前线人员”,他们必须有一种方式礼貌地将请求推迟到“现在不行”的类别(通常称为“待办事项列表”)。工程经理、产品经理和项目经理需要为团队建立一个将请求放入待办事项列表的已知流程,这样一线工程师就不会对说“现在不行”感到尴尬。一线工程师还需要了解如何在对话变得困难时,将请求升级给能代表团队说“现在不行”的经理。

大多数客户对“现在不行”是可以接受的,只要他们大致知道何时能得到结果。你不必为所有请求提供确切的日期。如果它们在遥远的将来,你可以说“明年”。如果它们在不久的将来,你的客户可能想要更精确的日期,不过每个人都应该理解,软件工程中的交付日期始终是一个估计。永远不要强迫开发者体验团队为了满足任意期限而交付一个糟糕的产品——那个糟糕解决方案给公司带来的成本将远远高于只是多等一周让开发者体验团队构建更好的东西。

对客户说“我们永远不会做这个”是最难给出的回应。感觉你很不友善。然而,你必须能够对确实会损害公司开发者体验多于帮助的请求说“抱歉,不行”。

例如,也许你正在替换一个旧系统,你的工作将需要一年时间,并且你从问题理解中知道新系统将为开发者体验带来显著改善。一个团队过来对你说,“我们需要你在旧系统上投入整整一个季度的工作量来改善我们的体验。”大多数情况下,这显然是一个“不”。如果他们一年后能得到一个很棒的结果,那么为了在现有系统上获得微小改进而推迟那个很棒的结果整整一个季度是没有意义的。

然而,你只有在有其他方式能让客户完成他们实际需要做的事情时才能说“不”。如果你让你的工具成为公司做事的唯一方式,并且有一个功能是你的客户必须拥有才能完成工作的,那么无论怎样,你都被迫要实现该功能。这就是为什么我主张任何开发者体验系统都应该有多个层级:

  • 一套低层的工具、库和基础设施,允许人们做任何他们需要做的事情,但使用起来很复杂。
  • 一个高层平台,使用简单,但要求客户以非常特定的方式工作才能利用它。

通常高层平台将涵盖80%的用例,而20%的用例需要“打破玻璃”,使用平台之下的工具。

这个系统的好处在于,高层平台可以(并且应该)非常积极地拒绝那些会损害平台使用体验的功能请求。当然,高层平台的负责人必须对问题有非常深刻的理解,从而知道真正需要构建什么。但高层平台的整个要义是为公司80%的开发者用例提供不可思议的体验,这意味着整个体验需要精心策划,你需要能够拒绝许多会降低使用体验的功能请求。

不过,只有当存在用户可以用来完成他们需要的任何事情的底层工具、库和基础设施(有时我们称之为“底层原语”)时,这才是可能的,这样你就可以告诉他们:“抱歉,高层平台不支持那个,但你仍然可以使用底层原语来完成你需要做的事情。”

善意

关于善意的一点说明:对你谈话的对象说“不”(甚至“现在不行”)可能感觉不友善。但是,通过对你本不该答应的请求说“是”,从而损害你不与之交谈的所有人的开发者体验,要更加不友善得多。

让制造痛苦的人承担痛苦

如果一个团队可以做出给另一个团队造成困难(“痛苦”)的事情,并且造成困难的团队自身从未因此感受到任何困难,那么所产生的痛苦将不断增长、增长、再增长。

这不是说团队有恶意。没有人想伤害他们的同事。这是关于自然激励以及人类如何应对这些激励。

假设你有一个团队拥有一个被其他十个团队使用的库。库团队有自己的目标、自己的截止日期和自己的优先级。他们专注于完成这些目标所必须做的事情。如果允许他们每天向客户发布破坏性变更,而他们自己却不会因此承受任何后果,那么他们就会每天发布破坏性变更,因为这是实现他们目标最高效、最有效的方式。库团队中可能有人认为他们不应该这样做,但随着时间的推移,业务压力将迫使他们无论如何都会那样做。

团队可能经历的“后果”有不同的形式,效果各不相同。最重要的是他们感受到这些后果的速度,以及他们感受到的困难程度与他们强加给客户的困难程度的对比。

令人惊讶的是,在这种情况下,像糟糕的绩效评估或人们对团队生气这样的人为后果效果最差。它们发生的时间远在痛苦产生之后,而且没有改变导致团队以这种方式行事的实际激励。它们只是让团队感到被压迫——他们做了必须做的事情,却因此被指责。那是不公正。

责任

解决问题的正确方法是改变谁必须做这项工作,从而改变团队的激励和基本的“物理定律”。我发现最有效的规则是:

如果一个团队想要进行变更,他们负责代表公司执行该变更。

如果你是一个库团队,想要进行一个破坏性变更,你必须重构所有客户的代码库以采用新的破坏性变更。如果你是一个网络安全团队,并且想要在公司所有代码库上实施新的控制措施,你必须自己将其安装到所有这些代码库中并确保其正常工作。

这需要大量的工具支持才能实现。你必须能够使用集中化的工具在整个公司范围内进行大规模变更。你必须有一些集中的方法来知道你推出某个变更时是否会破坏他人。你必须能够了解依赖你库或系统的每一个消费者,从而知道需要在何处进行更改。这方面有很多工作要做。但它极大地改变了企业的文化、基础设施团队(包括开发者体验团队)的有效性,以及公司开展工作的整体能力。它将基础设施团队从工作创造者转变为杠杆提供者,减少了公司采用变更所需的总工作量,并显著提高了整个业务中有益变更的速度。

局限性

这种模式有很多需要了解的。例如,基础设施提供者与其客户之间必须有关于哪些变更将被自动化以及变更破坏时谁负责修复的契约。例如,在Google,我们开玩笑地称之为“碧昂斯规则”,即“如果你喜欢它,你就应该给它一个测试”。换句话说,如果一个基础设施团队试图推出某个东西,并且在某个客户的自动化测试中断了,那么修复问题是基础设施团队的工作。如果一个基础设施团队试图推出某个东西,并且即使客户的系统实际上坏了也没有测试失败,那么修复问题就是客户的责任。

现在,你确实希望推动中心团队尽可能多地自己进行重构——他们倾向于避免查看客户的代码库,因为面对一个不熟悉的代码库很困难。因此必须推动团队实际集中做这项工作。(例如,你可以在工具中加入一项检查,强制执行“如果你要发送超过100个PR或向超过10个团队提交工单,必须有一个委员会审查你的变更,该委员会有某些指导方针,将要求你尽可能自动化大部分工作。”)

然而,中心团队实际能做的事情是有限的。确实存在客户必须做手动工作来采用变更的合理情况。你需要确保中心团队首先尽可能自动化。如果你要求客户做手动工作,你需要确保你提供的说明尽可能清晰——理想情况下,自己至少尝试一次以确保它实际上可以完成、有意义等。此外,还必须控制任何给定时间点公司被要求做多少手动工作。因此,如果你需要完成大量的手动工作,这必须经过某个中央委员会的批准,以确保公司不会一次经历太多的“变动”(手动或破坏性变更)。

尽管如此,有时自动化并不值得。如果你的变更需要两个团队做三小时的工作来采用,而自动化则需要你自己的团队投入20小时的工作,那就不要做自动化。

结语

以上就是我能想到的关于如何打造卓越开发者体验的所有基本原则。上述每一点还有更多需要了解的,足以写一本书,或者连续谈论十个小时(至少)。但就我此刻所能想到的,上面涵盖了每个领域需要了解的所有核心概念。

当然,你也希望确保开发者工作的结果是高质量的,因为软件的最终目的是尽可能多地帮助人们。并且你希望确保最终的系统是简单的(意味着易于阅读、理解和正确修改),以便能够长期轻松维护。然而,这些要点主要是在你实施上述系统时需要牢记。它们大多不是通过工具来实现的,而是通过每个软件开发者在其日常工作中理解并应用软件设计的基本原则来实现的。工具对于促成这些事情发生非常重要,工具开发者不能忘记它们,但这不像你只是将新工具、库、基础设施或平台发布出去,这些品质就会神奇地出现在每个代码库中。它们是公司中每个软件工程师持续的责任。

尽管如此,我希望我在这里写的内容有所帮助,我很想知道它是否有助于改善你或你公司开发者的生活,或者只是听听你对其中任何内容的看法。

-Max

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计