How to Write an Effective Software Design Document

How to Write an Effective Software Design Document

如何撰写一份有效的软件设计文档

A good design doc can save you years of development time. Writing a design doc forces you to think through important decisions before you waste time on the wrong implementation or paint yourself into a corner. It’s also the best way to coordinate design decisions among teammates and partner teams. 一份优秀的设计文档可以为你节省数年的开发时间。撰写设计文档能强迫你在浪费时间进行错误的实现或陷入困境之前,深思熟虑地做出重要决策。这也是在团队成员和合作伙伴之间协调设计决策的最佳方式。

I’ve written design docs as a developer at Google, Microsoft, and within my own companies. The specifics vary, but the underlying principles remain the same. A design doc should articulate the hard problems you’re solving and help your teammates give you feedback. 我曾作为 Google、Microsoft 以及我个人公司的开发人员撰写过设计文档。虽然具体细节各异,但其核心原则是一致的。一份设计文档应当清晰阐述你所要解决的难题,并帮助你的团队成员为你提供反馈。

Below, I share my approach to creating effective design docs and explain what belongs in a design doc and what does not. 在下文中,我将分享我创建有效设计文档的方法,并解释哪些内容应该包含在设计文档中,哪些则不应该。


An example design doc

设计文档示例

When should you write a design doc? 何时应该撰写设计文档?

How much should you invest into your design doc? 你应该在设计文档上投入多少精力?

What belongs in a design doc? 设计文档应包含什么?

What’s the cost of getting it wrong? 决策失误的代价是什么?

Components of a design doc

设计文档的组成部分

Title, Metadata, Objective, Background, Related documents, Goals, Non-goals, Scenarios, Diagrams, Glossary, Constraints, Service level objectives (SLOs), Monitoring / alerting, Timeline, Interfaces, Dependencies / infrastructure, Security, Privacy, Legal considerations, Logging, Open issues, Resolved issues, Alternatives considered, Driving Your Design Doc through Review. 标题、元数据、目标、背景、相关文档、目标(Goals)、非目标(Non-goals)、场景、图表、术语表、约束条件、服务等级目标 (SLOs)、监控/告警、时间线、接口、依赖项/基础设施、安全性、隐私、法律考量、日志记录、待解决问题、已解决问题、备选方案评估、推动设计文档的评审流程。


An example design doc

设计文档示例

The most common question I get about design docs is where to find a good one. I’ve never seen a public design doc that I consider high-quality. All of mine are hidden away at the companies that paid me to write them. 关于设计文档,我被问到最多的问题是去哪里找一份好的范例。我从未见过我认为高质量的公开设计文档。我所有的文档都保存在那些雇佣我撰写它们的公司的内部系统中。

So, I wrote a design doc from scratch based on the principles I’m sharing here. It lays out the design for a real web app I’m building. I created the design doc before writing any code, and I’m adhering to the design as I implement the app. 因此,我根据在此分享的原则,从零开始撰写了一份设计文档。它展示了我正在构建的一个真实 Web 应用的设计方案。我在编写任何代码之前就创建了这份文档,并且在实现应用时严格遵循该设计。

The design is more exhaustive than what I’d normally write for a solo hobby project, but this is roughly the length and depth of a design doc I’d create if I were coordinating work with other people on a professional project. 这份设计比我通常为个人业余项目撰写的要详尽得多,但这大致就是我在专业项目中与他人协作时所创建的设计文档的长度和深度。


When should you write a design doc?

何时应该撰写设计文档?

The more complex or risky the project, the more valuable it is to write a design doc. Consider these questions: 项目越复杂或风险越高,撰写设计文档的价值就越大。请考虑以下问题:

  • Will multiple people coordinate work to implement the design?
  • 是否会有多人协作来实现该设计?
  • Will the project take more than three months of full-time dev work?
  • 该项目是否需要超过三个月的全职开发工作?
  • Will the implementation run in production for several years?
  • 该实现是否会在生产环境中运行数年?
  • Does the project involve cross-team collaboration?
  • 该项目是否涉及跨团队协作?
  • Are the goals and requirements of the project ambiguous?
  • 项目的目标和需求是否模糊不清?
  • Are there catastrophic risks you could prevent at design time (e.g., security flaws, legal risks)?
  • 是否存在可以在设计阶段预防的灾难性风险(例如安全漏洞、法律风险)?

If you answered “yes” to any of these questions, then it’s likely worth the effort to write a design doc. If you answered “yes” to two or more, a design doc will almost certainly be worth the effort. 如果你对上述任何一个问题的回答是“是”,那么撰写设计文档通常是值得的。如果你对两个或更多问题的回答是“是”,那么撰写设计文档几乎肯定是非常值得的。


How much should you invest into your design doc?

你应该在设计文档上投入多少精力?

A design doc can be a simple one-pager or a 50-page document that requires signoff from five different teams. You need to decide how much detail makes sense. 设计文档可以是一页纸的简单说明,也可以是需要五个不同团队签字确认的 50 页长文。你需要决定多少细节是合理的。

There’s no universal rule that says how long you should spend on a design doc just like there’s no rule that says how much to test your code. The right investment depends on your team’s goals, risks, deadlines, and culture. Sometimes, the right amount to invest in a design doc is zero. 没有通用的规则规定你应该在设计文档上花费多少时间,就像没有规则规定你应该花多少精力测试代码一样。合适的投入取决于你团队的目标、风险、截止日期和文化。有时,在设计文档上投入零精力也是合理的。


What belongs in a design doc?

设计文档应包含什么?

If you specify every possible detail in a design doc, you’ve essentially written the implementation during the design phase. That would defeat the whole purpose of a design doc. 如果你在设计文档中指定了每一个可能的细节,那么你本质上是在设计阶段就完成了实现。这违背了设计文档的初衷。

As a rule of thumb, you can ask a simple question to decide whether a decision belongs in your design doc: what’s the penalty for being wrong? 作为一个经验法则,你可以问一个简单的问题来决定某项决策是否应该放入设计文档:如果决策错误,代价是什么?


What’s the cost of getting it wrong?

决策失误的代价是什么?

Not all design decisions are equally important. Some choices are radically more flexible than others. 并非所有的设计决策都同等重要。有些选择比其他选择灵活得多。

For example, if you build a web application in C++ and realize 200k lines later that Ruby on Rails was the better choice, you’re stuck. A from-scratch rewrite would never work, and even if you manage to write new code in Rails, you still suffer the burden of maintaining code in two wildly different languages. 例如,如果你用 C++ 构建一个 Web 应用,在写了 20 万行代码后才意识到 Ruby on Rails 是更好的选择,那你就会陷入困境。从头重写几乎不可能,即使你设法用 Rails 编写了新代码,你仍需承担维护两种截然不同语言代码的负担。

Other design decisions are trivial. For example, if your app displays a list of 1,000 articles, should they all appear at once? Or should the user see 20 at a time and click “Load more” to see the next 20? It doesn’t matter. 其他设计决策则微不足道。例如,如果你的应用要显示 1,000 篇文章的列表,是应该一次性全部显示?还是让用户一次看 20 篇,然后点击“加载更多”查看下 20 篇?这并不重要。

A “load more” button is not a design-level concern. If you pick one solution, and user feedback tells you you’re wrong, you can fix it in a few hours. You don’t need to detail your entire thought process in your design doc, and you definitely shouldn’t waste review cycles arguing about it. “加载更多”按钮不是设计层面的问题。如果你选择了一种方案,而用户反馈告诉你错了,你可以在几小时内修复它。你不需要在设计文档中详细说明你的整个思考过程,更不应该浪费评审时间去争论它。


Components of a design doc

设计文档的组成部分

Below, I’ve included common sections to include in your design docs. You generally don’t need every single section for every doc. Choose the subset that make sense for you. 在下文中,我列出了设计文档中常见的组成部分。通常你不需要在每份文档中包含所有部分,请选择适合你的部分。

Title

标题

The first thing your project needs is a title. It’s the way people will refer to your project in conversation, so aim for something with these qualities: 你的项目首先需要一个标题。这是人们在交流中提及你的项目时所用的名称,因此请确保它具备以下特质:

  • Short: Easy to say aloud. (简短:易于口头表达。)
  • Distinctive: Makes it clear which project it refers to. (独特:明确指向特定项目。)
  • Evocative: Conceptually represents your project. (形象:在概念上代表你的项目。)

For example, if you were adding a caching layer between your application server and your database server, RecencyBank would be a good name. It’s easy to say and describes your project’s purpose. A bad name would be “Project Flying Silver Horse” because it’s verbose and nonsensical. 例如,如果你要在应用服务器和数据库服务器之间添加一个缓存层,“RecencyBank”就是一个好名字。它易于朗读且描述了项目的目的。而“飞翔的银马项目”就是一个糟糕的名字,因为它冗长且毫无意义。

Metadata

元数据

Boring but useful, metadata helps your reader understand the basic context of your doc: 元数据虽然枯燥但很有用,它能帮助读者理解文档的基本背景:

  • Who is the author? (name + email address) (作者是谁?姓名+邮箱)
  • When did you create the doc? (文档创建时间)
  • What’s the authoritative URL? (权威链接地址)

Metadata 元数据

Objective

目标

The objective is a one-sentence explanation of your project’s purpose. It should appear on the first page of your doc in plain language that any stakeholder understands. 目标是对项目目的的一句话解释。它应该出现在文档的第一页,并使用任何利益相关者都能理解的通俗语言。

Objective 目标 Improve application performance by adding a caching layer between the Trogdor web server and the Postgres database. 通过在 Trogdor Web 服务器和 Postgres 数据库之间添加缓存层来提高应用性能。