谷歌是如何学技术文档的

Google软件工程文化的一个关键要素是使用设计文档来定义软件设计。这些相对非正式的文件由软件系统或应用程序的主要作者在开始编码项目之前创建。设计文档记录了高层次的实现策略和关键设计决策,重点强调在这些决策过程中考虑到的权衡。

作为软件工程师,我们的任务不仅仅是生成代码,而更多地是解决问题。像设计文档这样的非结构化文本可能是项目生命周期早期解决问题更好的工具,因为它可能更简洁易懂,并且以比代码更高层次的方式传达问题和解决方案。

除了原始软件设计文件外,设计文档还在以下方面发挥着作用:

在进行变更时及早识别出设计问题仍然较便宜。

在组织内达成对某个设计方案的共识。

确保考虑到跨领域关注点。

将资深工程师们掌握知识扩展到整个组织中去。

形成围绕设计决策建立起来的组织记忆基础。

作为技术人员投资组合中一份摘要性产物存在于其中。

设计文档的构成

设计文档是非正式的文件,因此其内容没有严格的指导方针。第一条规则是:以对特定项目最有意义的形式编写。

话虽如此,事实证明,某种结构已经被证明非常有用。

上下文和范围

本节为读者提供了新系统构建的大致概述以及实际正在构建的内容。这不是一份需求文档。保持简洁!目标是让读者迅速了解情况,但可以假设有一些先前的知识,并且可以链接到详细信息。本节应完全专注于客观背景事实。

目标和非目标

列出系统目标的简短项目列表,有时更重要的是列出非目标。请注意,非目标并不是否定性的目标,比如"系统不应崩溃",而是明确选择不作为目标而合理可能成为目标的事项。一个很好的例子就是"ACID兼容性";在设计数据库时,您肯定想知道是否将其作为一个目标或非目标。如果它是一个非目标,则仍然可以选择提供该功能的解决方案,前提是它不会引入阻碍实现这些目标的权衡考虑。

实际设计

这一部分应该以概述开始,然后进入细节。

设计文档是记录你在软件设计中所做的权衡的地方。专注于这些权衡,以产生具有长期价值的有用文档。也就是说,在给定上下文(事实)、目标和非目标(需求)的情况下,设计文档是提出解决方案并展示为什么特定解决方案最能满足这些目标的地方。

撰写文件而不是使用更正式的媒介之一的原因在于提供灵活性,以适当方式表达手头问题集。因此,并没有明确指导如何描述设计。

话虽如此,已经出现了一些最佳实践和重复主题,在大多数设计文档中都很合理:

系统上下文图

在许多文档中,系统上下文图非常有用。这样的图表将系统显示为更大的技术环境的一部分,并允许读者根据他们已经熟悉的环境来理解新设计。

一个系统上下文图的示例。

APIs

如果设计的系统暴露出一个API,那么草拟出该API通常是个好主意。然而,在大多数情况下,应该抵制将正式接口或数据定义复制粘贴到文档中的诱惑,因为这些定义通常冗长、包含不必要的细节,并且很快就会过时。相反,重点关注与设计及其权衡相关的部分。

数据存储

存储数据的系统可能需要讨论如何以及以什么样的形式进行存储。与对API的建议类似,出于同样的原因,应避免完全复制粘贴模式定义。而是专注于与设计及其权衡相关的部分。

代码和伪代码

设计文档很少包含代码或伪代码,除非描述了新颖的算法。在适当的情况下,可以链接到展示设计可实现性的原型。

约束程度

影响软件设计和设计文档形状的主要因素之一是解决方案空间的约束程度。

在极端情况下,有一个"全新软件项目",我们只知道目标,解决方案可以是任何最合理的选择。这样的文档可能涉及范围广泛,但也需要快速定义一组规则,以便缩小到可管理的解决方案集。

另一种情况是系统中可能存在非常明确定义的解决方案,但如何将它们结合起来实现目标并不明显。这可能是一个难以更改且未设计为满足您期望功能需求的遗留系统,或者是需要在主机编程语言约束下运行的库设计。

在这种情况下,您可能能够相对容易地列举出所有可以做到的事情,但需要创造性地将这些事物组合起来实现目标。可能会有多个解决方案,并且没有一个真正很好,在识别了所有权衡后该文档应专注于选择最佳方式。

考虑的替代方案

本节列出了其他可能达到类似结果的设计方案。重点应放在每个设计方案所做的权衡以及这些权衡如何导致选择文档主题中所述设计的决策上。

尽管对于最终未被选中的解决方案可以简洁地进行描述,但是这一部分非常重要,因为它明确展示了根据项目目标而选择该解决方案为最佳选项,并且还说明了其他解决方案引入了不太理想的权衡,读者可能会对此产生疑问。

交叉关注点

这是您的组织可以确保始终考虑到安全、隐私和可观察性等特定的交叉关注点的地方。这些通常是相对简短的部分,解释设计如何影响相关问题以及如何解决这些问题。团队应该在他们自己的情况下标准化这些关注点。

由于其重要性,Google项目需要有专门的隐私设计文档,并且还有专门针对隐私和安全进行Review。尽管Review只要求在项目启动之前完成,但最佳实践是尽早与隐私和安全团队合作,以确保从一开始就将其纳入设计中。如果针对这些主题有专门文档,则中央设计文档当然可以引用它们而不详述。

设计文档的长度

设计文档应该足够详细,但又要短到忙碌的人实际上能读完。对于较大的项目来说,最佳页数似乎在10-20页左右。如果超过这个范围,可能需要将问题拆分成更易管理的子问题。还应注意到,完全可以编写一个1-3页的"迷你设计文档"。这对于敏捷项目中的增量改进或子任务尤其有帮助 - 你仍然按照长篇文档一样进行所有步骤,只是保持简洁,并专注于有限的问题集合。

何时不需要编写设计文档

编写设计文档是一种额外的工作量。是否要编写设计文档的决策取决于核心权衡,即组织共识在设计、文档、高级Review等方面的好处是否超过了创建文档所需的额外工作量。这个决策的核心在于解决设计问题是否模糊------因为问题复杂性或解决方案复杂性,或者两者都有。如果不模糊,则通过撰写文档来进行流程可能没有太大价值。

一个明确的指标表明可能不需要文档是那些实际上只是实施手册而非设计文档。如果一个文件基本上说"这就是我们将如何实现它",而没有涉及权衡、替代方案和解释决策(或者解决方案显然意味着没有任何权衡),那么直接编写程序可能会更好。

最后,创建和Review设计文档所需的开销可能与原型制作和快速迭代不兼容。然而,大多数软件项目确实存在一系列已知问题。遵循敏捷方法论并不能成为对真正已知问题找到正确解决方案时间投入不足的借口。此外,原型制作本身可以是设计文档创建的一部分。"我尝试过,它有效"是选择一个设计方案的最佳论据之一。

设计文档的生命周期

设计文档的生命周期包括以下步骤:

创建和快速迭代 Review(可能需要多轮) 实施和迭代 维护和学习

创作和快速迭代

你撰写文档。有时与一组合著者共同完成。

这个阶段很快进入了一个快速迭代的时间,文档会与那些对问题领域最了解的同事(通常是同一个团队的人)分享,并通过他们提出的澄清问题和建议来推动文档达到第一个相对稳定版本。

虽然你肯定会找到一些工程师甚至团队更喜欢使用版本控制和代码Review工具来创建文档,但在谷歌,绝大多数设计文档都是在Google Docs中创建并广泛使用其协作功能。

Review

在Review阶段,设计文档会与比原始作者和紧密合作者更广泛的受众分享。Review可以增加很多价值,但也是一个危险的开销陷阱,所以要明智地对待。

Review可以采取多种形式:较轻量级的版本是将文档发送给(更广泛的)团队列表,让大家有机会看一下。然后主要通过文档中的评论线程进行讨论。在Review方面较重型的方式是正式的设计评审会议,在这些会议上作者通常通过专门制作的演示文稿向经验丰富、资深工程师们展示该文档内容。谷歌公司许多团队都定期安排了此类会议,并邀请工程师参加审核。自然而然地等待这样的会议可能会显著减慢开发过程。工程师可以通过直接寻求最关键反馈并不阻碍整体审核进度来缓解这个问题。

当谷歌还是一家较小的公司时,通常会将设计发送到一个中央邮件列表,高级工程师会在自己的闲暇时间进行Review。这可能是处理公司事务的好方法。其中一个好处是确立了相对统一的软件设计文化。但随着公司规模扩大到更庞大的工程团队,维持集中式方法变得不可行。

此类Review所添加的主要价值在于它们为组织的集体经验提供了融入设计的机会。最重要的是,在Review阶段可以确保考虑到横切关注点(如可观察性、安全性和隐私)等方面。Review的主要价值并非问题被发现本身,而是这些问题相对早期地在开发生命周期内被发现,并且修改仍然相对廉价。

实施和迭代

当事情进展到足够程度,有信心进一步Review不需要对设计进行重大更改时,就是开始实施的时候了。随着计划与现实的碰撞,不可避免地会出现缺陷、未解决的需求或者被证明错误的猜测,并且需要修改设计。强烈建议在这种情况下更新设计文档。作为一个经验法则:如果设计系统尚未发布,则绝对要更新文档。在实践中,我们人类很擅长忘记更新文件,并且由于其他实际原因,变更通常被隔离到新文件中。这最终导致了一个类似于美国宪法带有一堆修正案而不是一份连贯文档的状态。从原始文档链接到这些修正案可以极大地帮助那些试图通过设计文档考古学来理解目标系统的可怜未来维护程序员们。

维护和学习

当谷歌工程师面对一个之前没有接触过的系统时,他们经常会问:"设计文档在哪里?"虽然设计文档(像所有文档一样)随着时间推移往往与现实脱节,但它们通常是了解系统创建背后思考方式最容易入手的途径。

作为作者,请你给自己一个方便,并在一两年后重新阅读你自己的设计文档。你做得对了什么?你做错了什么?如果今天要做出不同决策,你会怎么选择?回答这些问题是作为一名工程师进步并改善软件设计技能的好方法。

结论

设计文档是在软件项目中解决最困难问题时获得清晰度和达成共识的好方法。它们可以节省金钱,因为避免了陷入编码死胡同而无法实现项目目标,并且可以通过前期调查来避免这种情况;但同时也需要花费时间和金钱进行创建和Review。所以,在选择项目时要明智!

在考虑撰写设计文档时,请思考以下几点:

您是否对正确的软件设计感到不确定,是否值得花费前期时间来获得确定性?

相关地,是否有必要让资深工程师参与其中,即使他们可能无法Review每个代码更改,在设计方面能提供帮助吗?

软件设计是否模糊甚至具有争议性,以至于在组织中达成共识将是有价值的?

我的团队是否有时会忘记在设计中考虑隐私、安全、日志记录或其他横切关注点?

组织中对遗留系统的高层次洞察力提供文档存在强烈需求吗?

如果您对以上3个或更多问题回答"是",那么撰写一个设计文档很可能是开始下一个软件项目的好方法。

Reference

www.industrialempathy.com/posts/desig...

相关推荐
陈随易1 小时前
农村程序员-关于小孩教育的思考
前端·后端·程序员
sre运维3 天前
运维人员必备的 Mac Zsh 配置技巧
程序员
陈随易4 天前
anime,超强JS动画库和它的盈利模式
前端·后端·程序员
陈随易4 天前
秦少卫-耗时5个月收入超过北京工资的超级独立开发者
前端·后端·程序员
陈随易5 天前
wangEditor,从开源、停更到重生
前端·后端·程序员
黑心萝卜三条杠5 天前
【Go语言】深入理解Go语言:并发、内存管理和垃圾回收
google·程序员·go
一只爱撸猫的程序猿6 天前
在SpringBoot 项目简单实现一个 Jar 包加密,防止反编译
spring boot·安全·程序员
TF男孩6 天前
独立开发上班后:我的故事,你的酒,一腔沉默往前走
程序员
肖哥弹架构6 天前
ScheduledThreadPool线程池设计/场景案例/性能调优/场景适配(架构篇)
java·后端·程序员
陈随易6 天前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员