谷歌的设计文档

2020-07-22 20:23:05

谷歌软件工程文化的关键元素之一是使用设计文档来定义软件设计。这些是软件系统或应用程序的主要作者或作者在着手编码项目之前创建的相对非正式的文档。设计文档记录了高级实施策略和关键设计决策,重点介绍了在这些决策过程中所考虑的权衡。

作为软件工程师,我们的工作不是生产代码本身,而是解决问题。非结构化文本(如设计文档形式)可能是在项目生命周期早期解决问题的更好工具,因为它可能更简洁、更容易理解,并且在比代码更高的级别上传达问题和解决方案。

除了软件设计的原始文档外,设计文档还在软件开发生命周期中完成以下功能:

设计文档是非正式文档,因此其内容不遵循严格的指导方针。规则1是:以任何对特定项目最有意义的形式来编写它们。

这一部分为读者提供了一个非常粗略的概述,介绍了正在构建新系统的环境以及实际正在构建的内容。这不是需求文档。要简明扼要!这样做的目的是让读者了解最新情况,但可以假设一些以前的知识,并可以链接到详细的信息。这一部分应该完全集中在客观背景事实上。

简要列出系统的目标是什么,有时更重要的是非目标是什么。注意,非目标不是像“系统不应该崩溃”那样被否定的目标,而是合理地可以成为目标,但被明确选择不是目标的东西。“ACID遵从性”就是一个很好的例子;在设计数据库时,您肯定想知道这是目标还是非目标。如果它不是一个目标,如果它不会引入妨碍实现目标的权衡,那么您仍然可以选择一个提供它的解决方案。

设计文档是记录您在设计软件时所做的权衡的地方。关注这些权衡,以生成具有长期价值的有用文档。也就是说,在给定上下文(事实)、目标和非目标(需求)的情况下,设计文档是建议解决方案并显示为什么特定解决方案最好地满足这些目标的地方。

通过更正式的媒介编写文档的目的是提供灵活性,以便以适当的方式表达手头的问题集。因此,对于如何实际描述设计,没有明确的指导。

话虽如此,出现了一些对大部分设计文档都有意义的最佳实践和重复主题:

在许多文档中,系统上下文图可能非常有用。这样的图表将系统显示为更大的技术版图的一部分,并允许读者在给定他们已经熟悉的环境的情况下将新设计与上下文联系起来。

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

存储数据的系统可能会讨论这种情况是如何发生的,以及以什么粗略的形式发生。与关于API的建议类似,出于同样的原因,应该避免复制-粘贴完整的模式定义。相反,将重点放在与设计相关的部分及其权衡上。

设计文档应该很少包含代码或伪代码,除非描述了新的算法。适当时,链接到显示设计可实施性的原型。

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

极端的一端是“绿地软件项目”,我们所知道的都是目标,而解决方案可以是任何最有意义的解决方案。这样的文档可能涉及面很广,但它还需要快速定义一组规则,这些规则允许放大一组可管理的解决方案。

在另一端是系统,其中可能的解决方案定义得非常好,但它们如何组合才能实现目标则一点也不明显。这可能是一个很难更改的遗留系统,也可能不是为实现您想要它做的事情而设计的,也可能是一个需要在宿主编程语言的约束内运行的库设计。

在这种情况下,你可能能够相对容易地列举出你能做的所有事情,但你需要创造性地把这些事情放在一起才能实现目标。可能有多种解决方案,但没有一个是真正优秀的,因此,考虑到所有已确定的权衡,这样的文档应该侧重于选择最佳方式。

本节列出了可以合理实现类似结果的替代设计。重点应该放在每个设计所做的权衡,以及这些权衡如何导致选择作为文档主要主题的设计的决定。

虽然简明扼要地说明最终未被选中的解决方案是很好的,但本节是最重要的部分之一,因为它非常明确地显示了为什么所选的解决方案是给定项目目标的最佳解决方案,以及读者可能会想知道的其他解决方案是如何引入在给定目标的情况下不太可取的折衷方案的。

这是您的组织可以确保始终考虑某些横切问题(如安全性、隐私和可观察性)的地方。这些通常是相对较短的部分,解释设计如何影响关注点以及如何解决关注点。团队应该标准化他们案例中的这些关注点。

由于它们的重要性,谷歌项目需要有专门的隐私设计文档,并且有专门的隐私和安全审查。虽然审查只要求在项目启动时完成,但最佳做法是尽早与隐私和安全团队接触,以确保设计从头开始考虑这些因素。对于这些主题的专用文档,中央设计文档当然可以参考它们,而不是详细介绍。

设计文档应该足够详细,但要足够简短,以便于忙碌的人阅读。大型项目的最佳位置似乎是10-20页左右。如果您超越了这一点,那么将问题分成更易于管理的子问题可能是有意义的。还应该注意的是,写一份1-3页的“迷你设计文档”是完全可能的。这对敏捷项目中的增量改进或子任务特别有帮助--您仍然要做与较长文档相同的所有步骤,只是让事情更简洁,并集中在有限的问题集上。

编写设计文档是一项开销。是否编写设计文档的决定归根结底取决于核心权衡,即决定围绕设计、文档、高级评审等达成的组织共识带来的好处是否超过创建文档的额外工作。决策的核心在于设计问题的解决方案是否含糊不清--是因为问题的复杂性还是解决方案的复杂性,还是两者兼而有之。如果不是,那么编写文档的过程就没有什么价值了。

文档可能不需要的一个明确标志是设计文档,它们实际上是实现手册。如果文档基本上只说“这就是我们将如何实现它”,而没有进行权衡、选择和解释决策(或者如果解决方案如此明显以至于没有权衡),那么立即编写实际的程序可能会是一个更好的想法。

最后,创建和审查设计文档的开销可能与原型和快速迭代不兼容。然而,大多数软件项目确实存在一组实际已知的问题。订阅敏捷方法并不是不花时间正确解决实际已知问题的借口。此外,原型本身可能是设计文档创建的一部分。“我试过了,很管用”是选择设计的最佳论据之一。

这一阶段很快演变成快速迭代的阶段,文档与对问题空间最了解的同事(通常属于同一团队)共享,并通过他们澄清的问题和建议将文档驱动到第一个相对稳定的版本。

虽然你肯定会发现工程师甚至团队更喜欢用版本控制和代码审查工具来创建文档,但Google的绝大多数设计文档都是在Google Docs中创建的,并大量使用其协作功能。

在评审阶段,与最初的一组作者和密切的合作者相比,设计文档将与更广泛的受众共享。评论可以增加很多价值,但它们也是一个危险的开销陷阱,所以要明智地对待它们。

评论可以有多种形式:更轻量级的版本只是将文档发送给(更广泛的)团队列表,让人们有机会看一看。然后,讨论主要发生在文档中的评论帖子中。在审查的繁重方面,是正式的设计审查会议,在这些会议上,作者向经常是非常资深的工程观众展示文档(通常通过专门的演示)。谷歌的许多团队都为此目的安排了周期性的会议,工程师们可以报名参加审查。自然,等待这样的会议可能会大大减慢开发进程。工程师可以通过直接寻求最关键的反馈,而不是阻碍更广泛审查的进展来缓解这一问题。

当谷歌还是一家较小的公司时,习惯上是将设计发送到一个中央邮件列表,高级工程师会在他们自己的空闲时间对它们进行审查。这很可能是为你的公司处理事情的一种很好的方式。一个好处是,它确实在整个公司建立了相对统一的软件设计文化。但随着公司规模扩大到更大的工程团队,维持集中化方法变得不可行。

这样的评审增加的主要价值在于,它们形成了将组织的综合体验融入到设计中的机会。最始终如一的是,确保设计考虑到可观察性、安全性和隐私性等横切问题,这是审查阶段可以确保的事情。审查的主要价值不在于发现问题本身,而在于这发生在开发生命周期的相对早期,此时进行更改的成本仍然相对较低。

当事情已经取得足够的进展,确信进一步的审查不太可能需要对设计进行重大更改时,就是开始实施的时候了。当计划与现实发生冲突时,不可避免地会出现缺陷、未解决的需求或经过深思熟虑的猜测,这些最终被证明是错误的,需要更改设计。强烈建议在这种情况下更新设计文档。经验法则是:如果设计的系统还没有出厂,那么一定要更新文档。在实践中,我们人类不善于更新文档,而且由于其他实际原因,经常将更改隔离到新文档中。这导致最终的状态更类似于美国宪法,只有一系列修正案,而不是一份一致的文件。从原始文档到这些修改的链接对于未来糟糕的维护程序员试图通过设计文档考古来理解他们的目标系统是非常有帮助的。

当谷歌工程师面对一个他们以前没有接触过的系统时,他们的第一个问题往往是“设计文档在哪里?”虽然设计文档和所有文档一样,随着时间的推移往往与现实脱节,但它们仍然通常是了解指导系统创建的思想的最容易获得的切入点。

作为作者,请帮您自己一个忙,一两年后重新阅读您自己的设计文档。你做对了什么?你哪里搞错了?今天你会怎么做才能做出不同的决定?回答这些问题是提升为工程师并随着时间的推移提高软件设计技能的一种很好的方式。

设计文档是围绕解决软件项目中最困难的问题来获得清晰度和达成共识的一种很好的方式。它们节省了资金,因为它们避免了落入无法实现项目目标的编码陷阱,而使用前期调查本可以避免这些问题;而且它们是要花钱的,因为创建和审查需要时间。所以,明智地选择你的项目吧!

您是否不确定正确的软件设计,前期花费时间来获得确定性是否有意义?

与此相关的是,让高级工程师参与设计会有帮助吗?高级工程师可能无法审查每一次代码更改。

软件设计是否模棱两可,甚至有争议,以至于围绕它达成组织共识将是有价值的?

我的团队有时会忘记在设计中考虑隐私、安全、日志记录或其他横切问题吗?

是否迫切需要文档来提供对组织中遗留系统设计的高层次洞察力?

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

既然你已经走到了这一步,在你最喜欢的社交媒体网络上分享这篇文章将受到高度赞赏,💖!如需反馈,请在推特上ping我。

Jaana Dogan说:@Cramforce中关于设计文档的另一篇很棒的文章。如果您不是在讨论权衡或尝试解决歧义,则可能不需要设计文档。答复。

理查德·塞罗特说:在谷歌,@Cramforce通过布局结构来解释设计文档,而当你不这样做的时候,你不需要写一个…。

Senthil说:@Cramforce就如何处理软件系统的设计文档做了一个简洁实用的概述。

点击该按钮将打开一个新窗口来撰写推文。带有本文URL的推文可能会显示为对本文的评论。