作为软件工程师,我们的工作本身不是编写代码,而是解决问题。
很多人问过我这样的问题:“如何写出一份好的设计文档?” 突然想起几年前看到过一篇总结,觉得写得很好。 我今天查找了原始文章(#anatomy-of-a-design-doc),发现它来自 Google。
以下是正文,文档比较长。
非结构化文本的形式(例如设计文档)可能是在项目生命周期早期解决问题的更好工具,因为它可能更简洁、更容易理解,并且它比代码和解决方案在更高的级别上传达问题。
设计文档除了软件设计的原始文档外,在软件开发生命周期中还发挥以下作用:
设计文件本质解析
设计文档是非正式文档,因此其内容不遵循严格的准则。
规则#1 是:以对特定项目最有意义的任何形式编写它们。
因此,文档结构可以有很多种。 话虽如此,必须有某些结构被证明是真正有用的。 例如,以下内容可能是有效文档所需要的内容。
1.1 背景和范围
本节为读者提供了对正在构建的新系统的环境以及实际正在构建的内容的非常粗略的概述。 这不是需求文档。 请保持简单! 目标是让读者了解最新情况,但可能假设有一些先验知识并链接到详细信息。 本节应完全关注客观背景事实。
1.2 目标和非目标
#目标和非目标
系统的目标是什么,有时更重要的是,非目标是什么。 请注意,非目标不是消极目标,例如“系统不应崩溃”,而是可以合理地作为目标的目标,但明确选择不作为目标。 一个很好的例子是“ACID 合规性”; 在设计数据库时,您肯定想知道这是目标还是非目标。 如果这不是目标,您仍然可以选择提供该目标的解决方案,前提是该解决方案不会带来阻碍实现目标的权衡。
1.3 实际设计
#实际设计
本节应从概述开始,然后详细介绍。
设计文档是记录设计软件时所做的权衡的地方。 请注意这些权衡,以生成具有长期价值的有用文档。 也就是说,在给定背景(事实)、目标和非目标(要求)的情况下,设计文档是建议的解决方案,并显示特定解决方案最能满足这些目标的地方。
以更正式的媒介编写文档的目的是为了以适当的方式表达手头的问题提供灵活性。
因此,对于如何实际描述设计没有明确的指导。
话虽如此,一些最佳实践和反复出现的主题已经出现,它们对大多数设计文档都有意义:
1) 系统上下文图 System-context-diagram
在许多文档中,SystemContextDiagram() 非常有用。 这些图表将系统显示为更大技术景观的一部分,并允许读者将新设计与他们已经熟悉的环境联系起来。
(系统上下文图示例)
2)API
如果您正在设计的系统公开了一个 API,那么映射该 API 通常是一个好主意。 然而,在大多数情况下,人们应该能够抵御将正式接口或数据定义复制到文档中的诱惑,因为这些定义通常很长,包含不必要的细节,并且很快就会过时。 相反,应关注与设计及其权衡相关的部分。
3)数字存储(数据存储)
存储数据的系统可能应该讨论这种情况如何以及以何种大致形式发生。 与 API 建议类似,出于同样的原因,应避免复制粘贴完整的架构定义。 相反,应关注与设计及其权衡相关的部分。
设计文档应该包含很少的代码或伪代码,除非描述新算法。 在适当的情况下写文件的软件,链接到显示设计可实现性的原型。
4)约束程度
影响软件设计和设计文档的主要因素之一是解决方案空间的受限程度。
一方面是“绿地软件项目”,我们只知道目标,而解决方案可能是最有意义的。 这样的文档可能很广泛写文件的软件,但它还需要快速定义一组规则,以扩展一组可管理的解决方案。
另一方面,系统中可能的解决方案已经明确定义,但如何将它们组合起来以实现目标却并不明显。 这可能是一个难以更改的遗留系统,并且不是为实现您想要的功能而设计的,也可能是一个需要在主机编程语言的约束下工作的库设计。
在这种情况下,您可能能够相对轻松地列出所有可以做的事情,但您需要创造性地将这些事情组合在一起才能实现您的目标。 可能有多种解决方案,但没有一个是真正出色的,因此考虑到所有已确定的权衡,此类文档应侧重于选择最佳方法来实现这一目标。
1.4 替代方案和考虑因素
本节列出了可以合理实现类似结果的替代设计。 重点应该放在每个设计所做的权衡以及这些权衡如何导致选择该设计作为文档的主要主题的决定。
虽然可以简要描述最终未选择的解决方案,但本节是最重要的部分之一,因为它非常清楚地说明了为什么所选的解决方案是给定项目目标的最佳解决方案,读者可能想知道其他解决方案如何引入更少的解决方案给定目标的理想权衡。
1.5 跨领域关注点
在这里,您的组织可以确保始终考虑某些跨领域问题,例如安全性、隐私性和可观察性。 这些通常是相对较短的部分,解释设计如何影响问题以及如何解决它。 团队应该标准化这些问题。
由于其重要性,谷歌项目需要有专门的隐私设计文档,并有专门的隐私和安全审查。 虽然审查只需要在项目启动时完成,但最佳实践是尽早与隐私和安全团队合作,以确保设计从一开始就考虑到这些审查。 对于这些主题的专门文档,中心设计文档当然可以参考它们,而不是详细讨论它们。
1.6 设计文件长度
设计文档应该足够详细,但又足够简短,以便忙碌的人可以阅读。 对于一个非常大的项目,最佳长度似乎是 10-20 页左右。 如果您超越了这一点,将问题分解为更易于管理的子问题可能是有意义的。
还应该指出的是,完全可以编写 1-3 页的“迷你设计文档”。 这对于敏捷项目中的增量改进或子任务特别有用 - 您仍然可以像处理较长的文档一样执行所有步骤,只需使事情更加简洁并专注于一组有限的问题即可。
何时不写设计文档
编写设计文档是一项开支。 是否编写设计文档的决定归结为核心权衡,即组织在设计、文档、高层审查等方面达成共识的好处是否超过创建文档的额外工作。 这个决定的核心是设计问题的解决方案是否不清楚——要么因为问题的复杂性,要么因为解决方案的复杂性,或者两者兼而有之。 如果不是这种情况,那么完成编写文档的过程就没有什么价值。
可能不需要文档的一个明显标志是设计文档实际上是一份实施手册。 如果文档基本上说“这就是我们将如何实现它”,而不进行权衡、替代方案和解释决定(或者如果解决方案是显而易见的,意味着没有权衡),那么它可能会立即编写实际程序是一个更好的主意好主意。
最后,创建和审查设计文档的开销可能与原型设计和快速迭代不兼容。 然而,大多数软件项目确实遇到了一系列实际已知的问题。 订阅敏捷方法并不是不花时间正确解决实际已知问题的借口。 此外,原型制作本身可能是设计文档创建的一部分。 “我尝试过,效果很好”是选择设计的最佳论据之一。
设计文档生命周期
设计文档生命周期的步骤包括:
1.快速创建和迭代
2. 审核(可以多轮)
3. 实现与迭代
4、维护与学习
3.1 创建和快速迭代期
您编写文档,有时与一组作者一起编写。
此阶段很快演变为快速迭代阶段,在该阶段,文档与最了解问题空间的同事(通常在同一团队中)共享,他们澄清的问题和建议推动文档成为第一个相对稳定的版本。
虽然您肯定会发现工程师甚至团队更喜欢使用版本控制和代码审查工具来创建文档,但 Google 的绝大多数设计文档都是在 Google Docs 中创建的,并大量使用其协作功能。
3.2 审查期限
在审查阶段,设计文档会与比原作者和密切合作者更广泛的受众共享。 评论可以增加很多价值,但它们也是一个危险的陷阱,所以要明智地对待它们。
回顾可以有多种形式:更轻量级的版本只是将文档发送到(更广泛的)团队列表,让人们有机会查看。 然后讨论主要在文档内的评论线程中进行。 审查的一个重要方面是正式的设计审查会议,作者在会上向非常高级的工程受众展示文档(通常通过专门的演示)。 Google 的许多团队都会为此定期召开会议,工程师可以报名参加评审。 当然,等待这样的会议召开可能会大大减慢开发进程。 工程师可以通过直接寻求最关键的反馈来缓解这个问题,而不是阻碍更广泛的审查的进展。
当谷歌还是一家规模较小的公司时,设计通常会被发送到一个中央邮件列表,高级工程师会在闲暇时对其进行审查。 这可能是为您的公司处理事务的好方法。 一个好处是它确实在整个公司建立了相对统一的软件设计文化。 但随着公司规模扩大到更大的工程团队,维持集中式方法变得不可行。 此类审查的主要附加价值是它们提供了将组织的综合经验纳入设计的机会。 最一致的是,审查阶段确保设计考虑可观察性、安全性和隐私等跨领域问题。 审查的主要价值不在于发现问题本身,而在于在开发生命周期的较早阶段发现问题,此时进行更改的成本仍然相对较低。
3.3 实施和迭代周期
当事情进展到足以确信进一步审查不太可能需要对设计进行重大更改时,就可以开始实施了。 当计划与现实发生冲突时,不可避免地会出现缺陷、未解决的需求或有根据的猜测,这些猜测最终被证明是错误的,需要进行设计更改。 在这种情况下,强烈建议更新设计文件。
根据经验:如果您设计的系统尚未发货,请务必更新文档。 事实上,我们人类不擅长更新文档,并且出于其他实际原因,更改通常会被分成新文档。 这最终导致了一个更类似于美国宪法的国家,有一系列修正案而不是一份一致的文件。 从原始文档到这些修改的链接可以极大地帮助未来的维护程序员通过设计文档考古学了解他们的目标系统。
3.4 维护学习期
当谷歌工程师面对一个他们以前从未使用过的系统时,他们的第一个问题通常是“设计文档在哪里?” 虽然设计文档与所有文档一样,随着时间的推移常常与现实不同步,但它们仍然是指导系统创建的想法的最容易进入的切入点。
作为一名作者,帮自己一个忙,在一两年后重新阅读你的设计文档。 你做对了什么? 你做错了什么? 今天你会采取什么不同的做法? 回答这些问题是提高工程师水平和提高软件设计技能的好方法。
综上所述
在解决软件项目中最困难的问题时,设计文档是获得清晰度和共识的好方法。 节省资金,因为它避免了无法实现项目目标的编码漏洞,并避免使用预调查; 它需要花钱,因为创建和审查需要时间。 因此,请为您的项目明智地选择!
在考虑编写设计文档时,请考虑以下事项:
如果您对其中 3 个或更多问题的回答是肯定的,那么设计文档可能是开始下一个软件项目的好方法。