卓越开发者体验 (DX) 的最佳实践指南

2025-06-10

卓越开发者体验 (DX) 的最佳实践

指南

什么是 DX?

当软件或系统的用户是开发者时,开发者体验 (DX) 等同于用户体验 (UX)。DX 描述的是开发者使用产品时的体验,无论是客户端库、SDK、框架、开源代码、工具、API、技术还是服务。DX 借鉴了用户体验设计(或人机交互)的一些理念和哲学,但在此基础上,着眼于现代技术和标准。

这为什么重要?

DX 的重要性与良好的用户体验的重要性相同。当产品拥有良好的 DX 时,用户会更满意,更愿意推广产品,并延长产品使用时间。快乐的开发者往往健谈,当我们互相推荐产品时,拥有最佳 DX 的产品总是名列前茅。以下是我总结的 DX 最佳实践。践行这些,您就离成功更近了一步。

指南

沟通

良好的沟通是获得良好开发者体验的关键。你与开发者沟通的方式决定了他们如何看待你和你的产品。

语气:真实、开放、诚实

你与开发者沟通的方式,对他们如何看待你和你的产品至关重要。开发者能嗅出废话,他们不喜欢空洞的言辞。如果你对开发者坦诚相待,他们会更加尊重你的产品。

如果您遇到数据泄露、漏洞、一段时间的宕机或数据丢失,请务必明确告知。创建状态页面和沟通系统,并使用它与开发人员沟通。请诚实地说明您的时间表,并及时提供任何事后分析或汇报。

利用产品论坛沟通产品路线图,并让开发者直接参与到这些优先事项中。与他们互动,了解他们的想法。

出色的文档

您的文档是您向客户发出的声音。那么,怎样才能写出优秀的文档呢?

编写文档时,务必将开发者视为初学者,不仅要了解你的技术(他们肯定是初学者),还要了解该技术所依赖的平台。如果你正在编写 NPM 模块的文档,请包含一个链接,说明如何安装 NPM,以及如何将代码添加到其他 JS 文件中。如果是 Ruby 的 gem,也同样如此。

文档语言的一致性也很重要。如果您的文档有多位贡献者,请确保他们都使用“函数”而不是“方法”,或者“包”而不是“模块”。这对于您自己产品相关的名词也很重要,例如使用“活动日志”而不是“日志”。保持一致可以防止读者迷失方向,避免反复猜测他们正在阅读的内容。

第三,文档的逻辑布局和结构非常重要。列出常用阅读材料,并按集成步骤的顺序排列文档。“概述”包含核心概念,然后是“入门”部分,包含安装和/或设置,这是一个很好的开始。接下来的内容取决于你的产品,但你应该根据你期望用户做什么来制定——只需记录下你的期望即可。

最后,文档的详细程度总是很重要的。说得再多也不嫌多。一句或几句额外的文字就能真正帮助到陷入困境的开发者。这意味着开发者会感到安心和得到支持,而不是愤怒地拨打你的支持热线。文档有时感觉像是最后一刻才做的事情,但放慢速度,投入精力在文档上,从长远来看会带来回报。

良好的发行说明和变更日志

发布新版本时,与开发人员保持沟通也至关重要。请清楚地解释新版本有哪些新功能、哪些功能曾经出现问题但现已修复(是的,请承认您的错误),以及此版本有哪些风险(例如,这可能会破坏x)。如果您能链接到公共问题跟踪器以获取更多详细信息,那就更好了。为什么?因为当开发人员想要了解版本更新时,他们希望能够快速浏览发行说明或更改日志,并尝试找到他们要查找的内容。他们可能会问“这个功能在哪个版本中被弃用了?”或“x 是在哪个版本中添加的?”或“他们在哪个版本中修复了我遇到的 bug?”。如果您能在发行说明中回答这些问题,那么您就成功了。发行说明也是指出已修复的安全漏洞的好地方,这显然会更有动力更新。开发人员应该始终有动力更新到最新版本。让他们使用最新版本还可以减少支持开销。

尊重标准和习语

在编写客户端库、SDK、API 等时,尊重行业和/或社区的标准以及前人的平台习惯用法非常重要。

尊重平台习惯和工具集

我日常工作的一部分就是开发 iOS SDK,因此在开发过程中,我必须时刻关注使用它的应用开发者。他们使用的 Xcode 是什么版本?他们用的是什么语言?Objective-C 还是 Swift?我该如何让这个 API 更好地与它们兼容?虽然这只是一个轶事,但重要的是,你也要考虑同样的问题。所以,你自己想想,人们用什么工具与我互动?他们是什么版本?它们有什么区别吗?

不要假设编程范式

人们很容易认为,因为你喜欢某种编程风格,别人也会喜欢,但事实并非总是如此。例如,如果你喜欢函数式编程,你可能会倾向于使用函数式接口编写库。请不要这么做。用简单的、更传统或标准的方式编写它,例如简单的 JS 与 Fluent 接口、简单的 Ruby 或简单的 Swift 与函数式 API,或者 Java Builder 模式与仅仅构造一个对象,然后还为给定的风格提供包装器或外观。这样,每个人都可以使用它,而没有人需要为了使用你的代码而学习新的编程风格。如果没有给定的范例,请选择最好的,最好是最有可能避免错误并快速学习的。

一致性

对于开发者来说,界面一致性至关重要。这与用户体验 (UX) 中的原因非常相似,它可以防止人们犯错。要与语言或平台的其他部分保持一致。例如,假设您有一个简单的库,它与终端通信并提供一个原生对象供使用。如果您编写的是 Java 或 C#,您的异步方法可能会暴露一个 Listener 模式,这与语言本身非常一致。但是,如果您编写的是 Swift,您的等效方法可能会暴露一个回调。如果它是 JavaScript,它也可能是一个回调,但它也可能是一个 Promise。通过研究其他代码(最终的真相来源是平台源代码本身),找出平台上的通用代码,然后使用它们。

如果无关紧要,那么在不同语言之间保持一致,但平台一致性是首要的。方法应该在不同平台上使用类似的名称,这样使用多种语言进行集成的开发者可以获得动力,通常也因为这样更简洁。这也与上文提到的“尊重平台习惯用法和工具集”有关,在为特定语言或平台发布代码时,请记住这一点。

做个好公民

对于嵌入到其他人代码(例如框架和库)中的代码,最好确保你的代码不会造成问题。如果有的话,你的代码应该比它所在的代码更好,因为这样就永远不会成为问题。

方法注释和文档

如果您要公开方法,请尝试使用注解来指示一些事项。某些语言(例如 Objective C 和 Swift)提供这些功能,而某些工具(例如 Android Annotations)也提供此功能。首先是可空性,您在此处传递给我的值可以为 null 吗?如果是,这意味着什么?方法返回的内容也可以为 null 吗?明确指出这些情况后,开发人员可以调整其代码风格,使其更具防御性,或者避免围绕这些情况进行编码。只需添加注解这样简单的事情,您就可以避免用户出现 NullException 或类似的异常。

其次,要充分记录。仔细记录每个参数和方法,并妥善命名。最好使用比内部名称更好的命名方式,以便初学者更容易理解。关于如何使用该方法、该方法所需的先决条件或后决条件、其工作原理的提示、其等效项或冗余项以及任何副作用的文档越多越好。

这不仅能帮助外部开发人员,还能让您的内部团队在代码更改时快速上手。良好的代码文档非常重要。“不要过度注释”和“代码应该自文档化”的常见规则并不适用于外部代码。文档越多越好,始终如此。这样做是为了减少困惑,避免支持热线电话响个不停。

方法移除和弃用

如果您想改变对某些外部方法的看法,您需要放慢速度,让您的开发人员适应。推荐的方法是引入新行为并弃用旧行为。弃用是指正在被新函数或类替换的函数或类。您不能只是删除函数或更改其行为,因为这几乎肯定会影响与其交互的其他代码。您应该始终先弃用旧方法,然后在将来更合适的主要版本(稍后会详细介绍)中移除已弃用的方法。弃用期至少应持续一个月,但最多可以持续几年。

您可能觉得我上面对弃用的定义有点傻,因为您之前已经看到并处理过它们,嗯,*确实如此 - *这是一种很好的沟通方式,而且您已经习惯了 - 所以当您是提供代码的人时,请自己做。

非冲突命名空间

如果您使用的编程语言不支持命名空间或包,那么您应该在代码中添加前缀以避免这种情况。这在 Objective-C 中相当常见,其中许多提供的类都带有 NS- 或 UI- 前缀。例如,我的代码前面会加上 SJ,这是我的名字,有时是基于项目名称的缩写。使用两个或三个字母(最好是三个)可以降低编译时出现错误的风险,因为您的代码可能会与其他代码中的代码重名。

如果您的语言支持命名空间和/或包,请确保它们也出于相同的原因进行配置。

线程

或许更适合移动开发,谨慎使用线程和进程。尝试使用辅助进程或后台进程来执行工作,这样诸如 UI 操作之类的操作就不会被代码阻塞。因此,在编写代码时,请牢记常见的多线程陷阱,并仔细测试。

开源(至少尝试一下!)

虽然我承认有些代码必须保持闭源,但如果没有强制要求,也可以开源。遵循开源最佳实践,这些实践本身就是良好数字化转型 (DX) 的一部分。这条建议与上一条大致相同,主要围绕良好的沟通。

为什么开源?

开源代码越来越受开发者的信任,而且据传闻,越来越多的开发者在其产品中只使用开源依赖项。他们可以查看源代码,查找并修复错误,还可以检查是否存在任何可疑代码并将其删除。

很棒的阅读我

优秀的自述文件包含哪些内容?完整列表请点击此处,简而言之,包含良好的描述、安装说明、优秀的示例(简单示例)、贡献指南以及所有已知问题。提供更多文档的链接也很棒。我看到的一些优秀项目还会特别推荐顶级贡献者或知名用户。

安全的贡献空间

为你的开源工作制定行为准则至关重要。你的用户可以是任何人,无论他们是谁,他们的贡献都应该受到欢迎和保护。行为准则(即使是 Github 默认的准则)很重要,只要你在违反时能够采取行动就行。创建一个安全的贡献空间,记住,这些人可能正在为你的公司创造价值,为什么不尽你所能为他们提供最好的服务呢?

开放 CI

如果可能,并且合理的话,也请开放你的 CI 系统。大多数托管的 CI 系统对于开源项目来说都是*免费*的,所以只需连接并绑定即可。这将使你更容易通过拉取请求 (PR) 进行贡献,也使你更容易审核、接受或拒绝贡献。有些人甚至建议更进一步,使用机器人。使用你认为需要的。更活跃的仓库需要更多的自动化来扩展。

让一切变得简单

让开发者轻松获取并集成你的产品。令人惊讶的是,许多产品都能从开发者的使用中受益,但却无法理解他们的想法。

明确定价

首先是明确的定价。任何开发者都不会点击“预订演示”按钮。让我们免费试用一下,或者刷信用卡试试。我们想知道定价是如何运作的,以及哪些变量决定了价格。如果这些对我们来说是合理的,那就更好了,例如,哪些因素会给您带来更多成本,比如更高的请求数量或更长的计算时间。

当然,基于价值的定价是可行的,您可能希望为更大的客户达成交易,但如果SpaceX可以拥有定价页面,那么您的软件产品也可以拥有。

自助服务选项

如上所述,我们希望能够自己使用它。我们不一定想签署定制合同,也不一定非要联系销售人员,或者支付实施费用。我们只想注册,当天集成,看看价格是否与我们获得的价值相符。当然,您的业务可能并非如此(这没关系),但这是对模式的一种妥协,你会错过一个自助服务市场。而且如上所述,开发人员很健谈,他们可能会把你的产品推荐给他们的朋友,而他们的朋友正在为你一直想要的那个客户工作,所以你永远不知道。当然,请自行判断。

版本控制

正确版本控制您的代码和产品。语义化版本控制(SemVer)是业界目前采用的规范,效果良好,您应该使用它。简而言之,版本号应该由三部分组成,即三个数字。例如,“XYZ”或“Major.Minor.Patch”。补丁版本用于修复错误。次要版本添加了小功能,而主要版本则删除了弃用的功能并发布了更重要的功能。因此,在进行版本控制时,请仔细考虑您真正应该使用的版本号,以便向开发人员传达该版本的影响。如果您花了两周时间进行更改,很遗憾,它可能最终只是一个补丁版本。版本号的*语义*更为重要。

包装

现在大多数语言都有一种或多种公认的代码分发方式。JS 有 NPM 和 Yarn,Ruby 有 RubyGems,C# 有 Nuget,Java 有 Maven,iOS 有 CocoaPods/Carthage/SPM(grr),Python 有 PIP……等等。您的代码也应该通过这种方式分发。当开发人员浏览您的安装文档时,他们会在第一段中寻找通过这些系统安装产品的那一行代码,例如 gem 'Sam' 或 npm install sam。花点时间生成与这些系统交互所需的文件,并使用 Git 标签和语义化版本控制 (SemVer) 来创建并推送版本给用户。

其次,如果打包系统支持代码签名或类似的安全功能,请务必使用它们,以便您的开发人员知道该软件来自您,并且不太可能受到损害。

尽力而为

最后,我们来谈谈有关产品实际质量的明显问题。

使用你自己的东西

如果您要交付任何开发人员会用到的产品,请务必像新开发人员一样进行测试。创建一个新项目,集成并测试。尽量排除开发环境中的任何误报,真正做到“吃自己的狗粮”。您这样做得越多,就越了解集成过程,从而能够发现文档、ReadMe 等文件中的漏洞。将这项任务交给团队中完全不熟悉该产品的人(如果您是单人开发,也可以交给朋友),看看他们发现了哪些令人困惑的地方,然后进行改进。

功能集

您的产品功能集必须符合开发者对竞争对手的期望。然而,您可能会发现一些他们忽略的功能,这可能表明用户体验 (UX) 存在问题,或者用户体验 (DX) 不佳。请咨询开发者缺少哪些功能,并利用这些至关重要的(且免费的)反馈来改进您的产品。优秀的产品还能够在负载下保持扩展性,或针对特定用途进行精心设计。此外,它还能及时关注最新的问题,并保持依赖项的更新。

这就是成就优秀 DX 的关键所在。总而言之,很多 DX 只是在做你作为开发者所期望的事情。设身处地为他们着想(抛开你对这个主题的了解),尝试了解你的期望,然后照做。

玩得开心

开发者和所有人一样,都喜欢享受乐趣。请保持所有互动都轻松愉快,让双方都感到愉快。记住:如果他们在使用你的产品,你们就属于同一个团队。你们只是两个人一起解决问题。运用你的团队合作技巧,让互动积极愉快。

需要帮助吗?请联系我,我可以为您和/或您的团队提供帮助。

喜欢这篇文章吗?请用表情符号回应我,或者留言表达你的感激之情。表达你的感激之情真的能让任何在互联网上创作内容的人继续前进——我们就是为你这么做的。

鏂囩珷鏉ユ簮锛�https://dev.to/samjarman/the-best-practices-for-a-great-developer-experience-dx-b3a
PREV
了解 Javascript 中的 .map()、.filter() 和 .reduce() 数组方法。
NEXT
专家或通才