原文:https://medium.com/machine-words/writing-technical-design-docs-71f446e42f2e
软件工程师一个重要的技能就是写技术设计文档(TDDs),也被称为工程设计文档(EDDs)。这篇文章我会谈些如何写好技术文档的建议和需要避免哪些错误。
提醒:不同的团队对技术设计会有不同的标准和习惯。对于技术设计没有全行业的标准,也不能有,不同的开发团队对他们的场景会有不同的需求。我要描述的是基于我经验的一个可能的答案。
设计过程
让我们从基本开始:什么是技术设计文档,它如何适合设计过程?
一个技术设计文档描述了给定技术问题的一个解决方案。他是一个设计说明,或者设计蓝图,对于一个软件程序或者功能。
技术设计文档的主要功能是和团队成员沟通要完成工作的技术细节。然而,有另一个目的也很重要:写技术设计文档的过程强迫你组织你的想法,考虑设计的每个方面,确认你没有疏漏任何事。
技术设计文档经常是大型开发步骤如下几步中的一步:
- 确定产品需求通常用产品需求文档(PRD)描述。PRD 定义了从用户或外界代理看系统需要做什么。
- 确定技术需求。产品需求翻译成技术需求 - 之前是系统需要完成什么,现在是怎么完成。这步的输出是技术需求文档(TRD)。
- 技术设计。这步包含上一步需求实现的技术描述。输出是 TDD。
- 实现。实现需求的步骤。
- 测试。基于 PRD TRD 进行测试确保实现了需求。
每步之间通常会有评审过程来保证没有错误。如果发现任何错误,误解或者歧义,必须在进入下一步前纠正。
这些步骤不是固定的,可以根据实际情况改变。例如:
- 对于不是很复杂的小型功能,步骤2和3经常会合并成一个文档。
- 如果功能需要实现很多未知功能或者需要一些调查,在最后的技术设计前可能需要先进行概念验证。
这个过程会发生在不同的开发粒度上。PRD / TRD / TDD 也许会包括一整个系统的设计,或者只有一个功能。在大多数情况下,这个过程是连环的 - 每个设计/实现基于前一步的工作。
TRD 和 TDD 的界线有时会比较模糊。例如,假设你要开发一个用 RESTful API 通讯的服务。如果目标是调用一个已经开发完有文档的 API,那么这个 API 的描述是需求的一部分,应该包含在 TRD 中。如果目标是开发一个新 API,那么这个 API 的描述是设计的一部分,应该包含在 TDD 中。(然而,需求文档仍然需要些什么 API 需要完成)
写 TDD
目前,最佳实践是在合作文档系统上写技术文档,像 Google Docs 或 Confluence;然而,这不是必须的。重要的是有个方法让你的团队成员能评论文档和指出错误和疏漏。
大多数 TDD 在1到10页之间。虽然 TDD 没有长度上限,但是太长的文档难以编辑和阅读。考虑把文档拆成单独步骤或者实现阶段。
图解法很有帮助;有很多在线工具可以在文档中添加图,像 draw.io) 或者 Lucidchart。你也可以用像 Inkscape 的离线工具来生成 SVG 图。
该文件应详尽;理想情况下,TDD作者以外的其他人应该可以按书面形式实施设计。例如,如果设计指定了一个 API 的实现,每个 API 端点都应该被记录。如果存在细微的设计选择,则应将其标出。
避免常见写作错误
我在TDD中遇到的最常见的错误可能是缺乏上下文。就是说,作者用他们能解决的尽可能少的文字写下了解决问题的方式。但他们没有提供有关问题所在,为什么需要解决或选择该特定解决方案的后果的任何信息。
而且,请务必记住可能的读者是谁,以及他们的理解水平。如果你用了一个读者可能不懂的术语,应该给它加个定义。
良好的预发和拼写也是有帮助的。而且,避免文字游戏或者“可爱”的拼写;程序员喜欢玩文字游戏,我见过不止一例过度的文字游戏导致因为误解导致浪费团队精力。可以偶尔为功能和系统选择幽默或者出彩,容易记住的名字,这样可以帮助人们记住他们。但是不要通过它来炫耀你多么聪明。
既然说到名字,要小心的选择他们;Mark Twain写过,“选择正确的单词,而不是第二个表亲”(Choose the right word, not it’s second cousin.)词汇量不多的工程师有个通病就是把一个词一遍又一遍的用在不同的事物上,导致混乱。例如,给一个类命名为"DataManager"是模糊的并且一点没说明它实际是做什么的;同样,叫"utils" 的包或目录可能包含任何东西。如果你需要一个更好的或更专业的词,可以查阅同义词库例如WordNet。
TDD模板
当写TDD时,有一个标准模板是有用的。下面是我在很多工程中使用的一个模板。记住这个模板根据实际使用的地方做修改;你可以删除不需要的部分,添加其他部分,或者修改标题。
<标题>TDD
作者:<你的名字>
介绍
基本原理
你想要做什么?现在的东西有什么问题?
背景
描述理解文档所需的历史背景,包括遗留注意事项。
术语
如果文档使用了特殊的单词或术语,列在这里。
非目标
如果有相关问题你决定不在这个设计中解决,但是有些人希望你解决,列在这里。
设计
首先对解决方案进行简要的描述,下面的章节会详细描述。
系统架构
如果设计由多个大型组件之间的协作组成,在此处列出这些组件,或者更好地包括设计图。
数据模型
描述数据怎么存储。这里可能包括数据库设计。
接口/API定义
描述组件之间如何交互。例如,如果有个 REST 接口,写出 URL,传输数据结构和参数。
业务逻辑
如果设计需要特殊的算法或逻辑,描述他们。
迁移策略
如果设计引起对现有系统的非向后兼容更改,请描述依赖于系统的实体将要迁移到新设计的过程。
影响
描述设计对系统整体性能,安全性和其他方面的潜在影响。
风险
如果有任何风险或未知数,请在此处列出。另外,如果还有其他研究要做,也要提及。
备选方案
如果还有其他可能的解决方案被考虑和拒绝,请在此处列出它们,以及未选择它们的原因。
当然,这些部分只是起点。您可以根据需要添加其他部分,例如“设计注意事项”,“摘要”,“参考”,“致谢”等。
TDD生命周期
在系统构建过程中,TDD将作为参考,以协调从事该项目的团队成员的活动。但是,在构建完成之后,TDD将继续存在并用作系统工作方式的文档。您可能要区分“当前”和“存档” TDD。
然而,有两个方面需要注意:
首先,随着系统的不断发展,TDD很快就会过时。使用已有两年历史的TDD作为参考的工程师可能会浪费大量时间来试图理解系统为何无法如所描述的那样工作。理想情况下,陈旧的TDD将被标记为已过时或已取代;实际上,这很少发生,因为团队倾向于专注于当前而不是过去的工作。 (使文档保持最新是每个工程团队都在努力的挑战。)
其次,TDD可能不包括与系统接口所需的所有信息。 TDD可能仅涵盖对现有系统的一组更改,在这种情况下,您将需要查阅较早的文档(如果存在)以了解整体情况。 TDD主要关注实现细节,这与那些只想调用API的人无关。
因此,不应将TDD视为实际用户或API参考文档的适当替代品。
最后
网络上还有许多其他文章,解释了如何编写出色的设计文档。不要只读这篇文章!阅读其他内容,然后选择适合您的各种想法。