← 设计与文档

设计与文档

如何写出漂亮容易理解的软件设计文档

·设计与文档

从读者、结构、图示、语言到评审与维护,系统说明怎样写出别人愿意读、读得懂、能照着做的软件设计文档。含模板、正反例,以及一篇图文并茂的完整样例。

好的设计文档不是把脑子里的东西倒出来,而是帮下一个打开文件的人,在最短时间里建立同一幅图:要解决什么、为什么这样选、系统怎么拆、风险在哪、下一步做什么。

「漂亮」在这里不是排版花哨,而是层次一眼能看见、重点不用翻三页、图文对得上。「容易理解」则是:读者不用猜你的省略,也不用先读完整个仓库才能读懂这一篇。


1. 先问三个问题

动手写之前,先能口头答完这三句。答不清,文档一定会散。

问题 答不清楚时的后果 写清楚后的效果
给谁看? 对架构师讲实现细节,对新人堆术语 深度和用语对得上读者
要他读完后做什么? 读完仍不知道该评审、该实现还是该反对 每节都指向一个决定或动作
不写会怎样? 口头对齐三次还是各做各的 只写「不写就会歪」的那些部分

常见读者不是同一种人,一篇文档里要标明主读者:

主读者超过两种时,宁可拆成「一页决策 + 一篇实现说明」,也不要揉成七十页百科。


2. 先选对文档类型

很多「难看」的文档,病根是类型错了:把会议纪要写成架构,把接口清单写成愿景。

类型 解决什么 篇幅建议 不该写什么
一页概述 新同学 10 分钟看懂系统 1~2 页 算法细节、票号流水账
RFC / 设计提案 还没拍板,征求反对意见 3~8 页 假装已经定了的实现
ADR(架构决策记录) 记下「选了 A 而不是 B」 1~2 页 整系统说明书
高层设计(HLD) 模块、数据流、部署、依赖 5~15 页 每个类的字段
详细设计(LLD) 关键路径、状态机、错误码 按模块拆 重复 HLD 的背景
接口约定 请求响应、鉴权、兼容策略 以表格为主 业务抒情

一条经验:决策用 ADR,结构用 HLD,细节用 LLD,对外契约用接口文档。 混在一处,读者会在「为什么」和「怎么写代码」之间反复迷路。

ADR 可以短到这种程度:

# ADR-0012:订单状态存在独立状态机服务

- 状态:已采纳
- 日期:2026-09-01
- 背景:订单状态原先散落在三个服务的 if/else 里,对账经常不一致。
- 决策:抽成独立状态机,其它服务只发命令、订事件。
- 备选:继续分散;或塞进现有订单服务。
- 后果:多一次网络调用;换来状态可审计、可回放。

短,但后人能看见当时的约束。这比空喊「微服务更好」有用得多。


3. 一份设计文档的推荐骨架

下面这套目录适合大多数中等复杂度的后端 / 平台设计。可以删节,不建议打乱顺序:读者习惯先背景后方案。

# 标题:一句话说清「给谁做什么」

1. 摘要(半页,可单独转发)
2. 背景与问题
3. 目标与非目标
4. 名词与范围
5. 方案概述(先给图)
6. 关键设计(数据、接口、状态、失败)
7. 取舍与备选
8. 风险、观测与发布
9. 开放问题
10. 附录(长表、错误码、会议链接)

3.1 标题和摘要

差标题:订单模块优化
好标题:订单履约:把状态机从三个服务收拢到一处,并保证对账可回放

摘要用五句话就够,建议固定句式:

  1. 现在怎样,痛在哪。
  2. 我们打算怎样改。
  3. 明确不做什么。
  4. 最大的风险是什么。
  5. 需要谁在何时拍板。

读者若只读摘要就能决定「要不要往下看」,这篇文档就已经赢了一半。

3.2 背景与问题:写事实,不写情绪

把问题写成可检验的句子

差:现在订单很乱,经常出 bug。
好:近 30 天对账失败 47 次,其中 31 次是「支付成功、履约仍为待支付」,根因是支付回调与库存扣减没有同一套状态源。

配一个「当前链路」简图,比再写三段文字更省事。背景里只放迫使你现在做决定的信息,公司创业史请删。

3.3 目标与非目标:最能让文档变薄的两栏

目标(做到算出成功) 非目标(这次坚决不做)
支付成功后 5 秒内履约状态一致 不重做结算与分账
任意一笔订单可回放状态变迁 不更换支付渠道
对账差异从周均 10+ 降到 1 以下 不在本迭代上跨城多活

非目标不是偷懒,是防止评审时被拖进无边需求。写下来,比会上说「那个以后再说」有效。

3.4 名词表:消灭同词异义

团队里最贵的误解,常常是同一个词。花半页列清楚:

名词 本文含义 不要理解成
订单 用户一次下单生成的履约单 购物车、支付单
已支付 支付渠道回调成功且本地落库 用户看见「付款成功」弹窗
冻结库存 预占,可释放 已出库

后文凡是用这些词,都按表走。比在段落里反复括号解释更干净。


4. 先画图,再写字

人脑对结构的理解,图快于字。漂亮的文档几乎都是图在前、字解释图,而不是字写完再补一张装饰图。

4.1 选对图,不要为了「看起来专业」堆图

你想说清的事 用什么图 常见滥用
系统由哪些块组成、谁依赖谁 模块图 / C4 容器图 把每个 jar 都画成六边形
代码怎么分层、依赖朝哪边 分层架构图 和部署图画在一张上,或画成没有方向的方块墙
一次请求怎么走 时序图 把重试、日志、监控全画进去
对象生命周期 状态机 用流程图冒充状态机(缺事件名)
数据从哪来、经过谁、落到哪 数据流图 线上不写数据名,或画成主从拓扑
进程跑在哪、几份、谁连谁 部署图 和分层图、类图画在同一张上
上线先后顺序 步骤泳道 和部署拓扑画在同一张上

分层架构图回答的是谁可以调用谁,不是机房拓扑。四层横条叠起来,箭头只朝下;哪一层放规则、哪一层碰 SQL,一眼能看出来。

接入层HTTP / 鉴权 / 参数校验

把请求收成命令。不写「能不能批」这种业务 if。

↓ 只传命令与查询,不传 HttpRequest

应用层用例编排

一个用例一个服务:开事务、调领域、发通知。不拼 SQL。

↓ 调用聚合与领域服务

领域层规则与状态机

业务不变量住在这里。仓储接口在本层定义,实现不在本层。

↓ 经接口访问外部,领域不 import 驱动

基础设施数据库 / 消息 / 外部系统

SQL、SMTP、SDK 只出现在这一层。换库不改上面三层。

接入层 应用层 领域层 基础设施 允许:只向下依赖
图 分层架构:依赖单向向下。常见滥用是把 Nginx、K8s、类图全塞进同一张「架构图」。

部署图回答的是跑在哪、几份、连哪台,不是包名怎么分层。机房或 VPC 画成框,进程写实例数,边上标端口和主从。

公网

员工浏览器
管理端
↓ TLS :443

接入 VPC

负载均衡 / Nginx2 台,会话不粘滞
↓ HTTP :8080

应用 VPC

DeviceLoan × 2无状态,可随时扩
逾期 Worker × 1扫 outbox / 发通知

应用不落本地盘。配置来自环境变量,开关 deviceloan.enabled

↓ 内网

数据 VPC

PostgreSQL 主写借单 / 设备
PostgreSQL 从只读对账,延迟 < 2s
SMTP逾期通知
网段 / VPC 本系统进程 已有存储 外部系统 连接(线上标端口) 注释
图 部署:谁在哪个网段、几份副本、主从与出站依赖。不要把分层里的 Controller 再画一遍。

一张图只回答一个问题。一张图上既有机房、又有类、又有产品路线图,一定难看。每种图的框和线各自有习惯,底稿见 4.5

4.2 时序图要写出失败,而不仅是成功

成功路径人人会画。真正让实现者和测试省事的,是超时、重复、乱序:

用户 -> 网关: 提交订单
网关 -> 订单: CreateOrder
订单 -> 库存: Freeze
库存 --x 订单: 超时
订单 -> 订单: 标记 pending_freeze,进入补偿
订单 --> 网关: 202 + 查询号

旁注三行即可:超时阈值、是否可重入、补偿谁来触发。比再写一页「我们会考虑异常情况」实在。

4.3 状态机把事件写在箭头上

状态是圆圈,事件是箭头上的字。只写「待支付 → 已支付」而不写「收到 PaymentSucceeded」,实现时一定会各写各的 if。

同时写明:

4.4 图的可读性细则

4.5 形状与连线:每种图一张底稿

选对图之后,还要约定框是什么、线是什么。下面七张是底稿:形状本身带语义,线上写含义。每张图下方有图例,和正文里的形状一一对应。写正文时只替换名字,不要改形状用法——圆圈忽然变成「服务器」,读者就得重新猜。

模块图 / C4 容器

人 / 角色 HTTPS 同步 本系统容器 圆角实线框 SQL 存储 圆柱 = 库 / 队列 事件 / 异步 外部系统 虚线框 + 浅底 实线 = 同步依赖,虚线 = 异步;箭头上写协议或用途,不要裸线。
人 / 角色 本系统容器 外部系统 数据存储 同步依赖(线上标协议) 异步 / 事件
图 模块图底稿:人、本系统、外部、存储四种形状;线只表达依赖方向。

分层架构图

上层(靠近用户) ↓ 允许:调用接口、向下依赖 下层(靠近存储 / 设备) 禁止向上 形状:整层一条横条,不要拆成散落的类方块。 线:只朝下。画成无方向的方块墙,等于没画分层。 不要在横条里再画 Nginx、K8s、机柜——那是部署图的事。
一层(整层一条横条) 允许:向下依赖 禁止向上
图 分层底稿:横条 = 一层;实心向下 = 允许;虚线折返 = 禁止倒依赖。

时序图

调用方 本服务 依赖 实线实心箭头 = 同步调用 虚线箭头 = 返回 Freeze 叉尾虚线 = 超时 / 失败 折回自己 = 内部动作 顶上写对象,竖虚线是生命线。时间从上往下。旁注写超时和是否可重入。 不要把日志、监控、重试策略全画成消息。
生命线 同步调用 返回 超时 / 失败 内部动作 旁注:超时、是否可重入
图 时序底稿:生命线、同步、返回、失败、自调用。失败必须能看见。

状态机

实心点 初态 状态 A 事件 [守卫] / 动作 状态 B 完成 双圈终态 Reject 也是终态 圆角框 = 状态,不是步骤。箭头上必须是事件名,不能只写「下一步」。 缺事件的状态图,其实是流程图,实现时会各写各的 if。
初态 状态 终态 转移:事件 [守卫] / 动作 拒绝 / 结束事件
图 状态机底稿:初态点、状态框、双圈终态;转移写「事件 [条件] / 动作」。

数据流图

员工 直角框 = 外部 申请 1.0 批准借用 圆 = 加工 借单 D1 借单 开口条 = 数据存储 占用 D2 设备 通知稿 SMTP 箭头上写数据名(名词),不写「调用」「POST」。每个加工至少一进一出。
外部实体 加工 数据存储 数据流(线上写名词)
图 数据流底稿:外部是直角框,加工是圆,存储是开口条;线上是数据,不是协议。

部署图

外部客户端 :443 TLS 虚线大框 = 节点 / VPC / 机房 进程 × 2 实线小框 = 可复制实例 :8080 库 主 边上写主从 复制 库 从 外部依赖 SMTP / 第三方 框是机器或网段,数字是副本。不要把 Controller、类名再画进来。
节点 / VPC 进程 × N 外部依赖 网络(线上标端口) 复制 注释
图 部署底稿:大虚线框圈住运行位置,小实线框是进程;连线写端口。

步骤泳道

开发 运维 系统 1 合并开关 2 灰度 10% 3 跑迁移 4 切读 5 观察 竖条 = 责任人,圆角框 = 步骤,箭头 = 先后或交接。框里写动词。 不要把 VPC 和副本数画进泳道——顺序和拓扑是两张图。
泳道 = 责任人 步骤(框里写动词) 起点 先后 / 交接
图 泳道底稿:列是谁来做,框是做哪一步,跨列箭头才是交接。

5. 把「关键设计」写成别人能实现的规格

概述解决「长什么样」,关键设计解决「碰到硬问题时怎么走」。下面四块几乎每篇中等设计都用得上。

5.1 数据:谁是源,谁是副本

写清:

差:订单和支付记录存在数据库里,用 Redis 加速。
好:订单主状态以orders表为准;Redis 只缓存只读展示,TTL 30s,缓存失败直接回表。支付回调以payment_id幂等,重复回调返回 200 且不推进状态。

5.2 接口:给例子,不要只给形容词

每一个对外接口至少具备:路径、调用方、成功示例、失败码、超时与重试、兼容策略。

POST /v1/orders/{id}/freeze-stock
Idempotency-Key: 8f2a...

# 成功
{ "status": "frozen", "expire_at": "2026-09-09T12:00:00+08:00" }

# 失败:库存不足
{ "error": "STOCK_INSUFFICIENT", "sku": "A01", "want": 2, "left": 0 }

「接口要优雅」「错误要友好」这类句子可以删。读者需要的是字段和码。

版本策略也要写死一句,例如:/v1 只追加字段,不改语义;破坏性变更走 /v2,旧版至少保留两个发布周期。

5.3 一致性:说人话,并落到机制

「我们保证最终一致」太空。改写成机制:

5.4 安全与权限:点名,不空喊

写清:谁能调、凭什么、敏感字段怎么脱敏、审计日志记什么。涉及钱、库存、隐私的设计,缺这一节就不该过审。


6. 语言:清楚比华丽重要

漂亮的中文技术文档,通常有这些习惯。

短句,主动语态。
差:库存的扣减将会在支付完成之后被进行。
好:支付成功后,订单服务调用库存冻结。

先结论后解释。 每节第一句就是答案,细节放后面。评审者时间少,实现者才会往下翻。

一次只引入一个新名字。 同一段里同时冒出「编排器、协调者、网关、门面」,没有人分得清。

数字要有单位和对比。 QPS 会很高 不如 高峰 1.2k QPS,现网峰值的 3 倍

少用程度副词。 「非常」「尽可能」「妥善」在设计里等于没写。改成阈值、超时、重试次数。

术语第一次出现给定义,之后保持稳定。 不要前一节 SLA、后一节 服务承诺、附录又变 可用性指标

删除正确的废话。 例如「随着业务发展,系统复杂度提升,我们需要更好的架构」。读者已经在读设计文档了,不用再被说服「设计有意义」。

可用的自检:把一节读给没参加讨论的同事听,他若不断问「这是什么意思」,那一节就还没写完。


7. 正反例:同一件事的两种写法

反例(常见病)

为了提升用户体验并赋能业务高质量发展,我们将对订单中台进行全面升级。新架构采用领域驱动与微服务理念,充分解耦,灵活扩展,后续可支撑各类创新场景。具体实现由各小组根据实际情况推进,遇事沟通。

读完不知道:改什么、不改什么、谁先上、失败怎么办。形容词很多,动词没有。

正例(同一主题)

决策: 把订单状态从支付、履约、库存三处,收拢到订单服务内的状态机;其它服务只发命令、订 order.events
不做什么: 不拆分结算,不换支付渠道。
成功标准: 支付成功后 5 秒内状态一致;对账差异周均 ≤ 1。
发布: 先双写一周,对账无差异再切读。回滚开关:order.state_machine.enabled

字数更少,能评审、能实现、能验收。

再看一处接口描述的对比。

差:前端调用后端获取数据,注意性能和安全。

好:

约定
调用 GET /v1/orders/{id},登录用户且为下单人
热点 详情页允许 50 QPS / 实例,超限 429
缓存 CDN 不缓存;网关缓存 0
脱敏 手机号中间四位 *,仅客服角色可见全文
失败 订单不存在 404;无权限 403,不泄露是否存在他人订单

8. 版式:少装饰,多对齐

「漂亮」多半来自克制。

  1. 标题是大纲。 读者只扫 h2 / h3 应能复述结构。不要出现「其它」「补充说明」这种垃圾桶标题。
  2. 一段一个意思。 超过八行就考虑拆,或改成列表。
  3. 能用表就不要用散文。 对比、字段、错误码、发布步骤,表比段落干净。
  4. 代码和配置用等宽块。 不要把 JSON 塞进一句话的引号里。
  5. 强调不超过一种。 加粗或引用,选一个。满屏加粗等于没有重点。
  6. 留白。 节与节之间空一行;图下写一句图注:图 2 支付成功后的补偿路径
  7. 链接写人话。 用「见 ADR-0012」而不是「点击这里」。

Markdown 足够写绝大多数设计文档。先把结构写对,再考虑 Wiki 皮肤和封面。


9. 评审:文档是用来被反对的

写完先自己当反对者,再发给别人。评审不是找错别字,是找没写出来的决定

请评审者只回答这几个问题:

  1. 问题是否真的存在?有没有更小的改法?
  2. 非目标是否被偷偷做大了?
  3. 失败路径有没有空洞?
  4. 数据以谁为准?冲突时听谁的?
  5. 发布和回滚能否在半夜独立做完?
  6. 三个月后,一个新人只读这一篇,能不能动手?

收集意见时,把「已采纳 / 不采纳 + 理由」写回文档或 ADR,不要只留在聊天记录。反对被记录下来,文档才算闭环。

评审前把文档冻一版(日期 + 链接)。边评边改到面目全非,参会的人会对着不同文本说话。


10. 维护:过期的漂亮文档比没有更危险

设计文档的寿命往往短于系统。要让它继续「容易理解」,得约定谁改、何时改。

文档和代码冲突时,以代码为准、并记一笔债。假装文档永远正确,是最常见的信任破产。


11. 样例:一份带分层架构的设计文档

下面整节就是一篇可以拿去评审的设计,主题是内部设备借用系统 DeviceLoan。核心不是堆接口,而是把软件拆成四层:接入、应用、领域、基础设施。依赖只允许从上往下。

主读者:实现者 · 评审者  状态:待拍板  核对:2026-09-09

11.1 摘要

行政现在用表格登记示波器、开发板、镜头的借还,近 90 天出现 11 次「账上在库、柜子是空的」。做一套内部借用系统:员工申请,管理员审批,借出与归还改库存,逾期发通知。

做: 申请、审批、借出、归还、逾期提醒。不做: 采购、折旧、对外租赁。架构: 四层,领域规则不进 Controller,SQL 不进领域对象。拍板: 本周五前行政与平台各一人签字。

11.2 背景与问题

设备 86 件,分散在 3 个柜子。登记本与即时通讯群并行,对不上时只能翻聊天记录。没有审批痕迹,也没有「谁持有」的唯一事实源。

员工
管理员
行政表格
↓ 口头申请、表格手改、群里确认,三套账
柜子实物
Excel「在库」
聊天记录
已有角色 / 账本 对不齐的关系
图 1 现状:没有唯一库存源,审批和持有人对不齐

11.3 目标与非目标

目标(可验收)非目标(本次不做)
任意时刻,一件设备至多一张「已借出」单据 不接财务、不算出资产原值
申请到审批的接口 P99 < 300ms 不做移动端原生 App、不扫码入库
逾期 T+1 个工作日发出通知,漏发率周均 < 1% 不支持跨园区调拨、不对接门禁

11.4 名词

名词本文含义不要理解成
设备可单独出借的一件实物,有唯一 asset_no设备型号、配件包
借单一次申请生成的聚合根 LoanOrder聊天里的口头答应
在库领域状态 available,可被新申请占用柜子里看得到但单据未还

11.5 分层架构

进程内四层。箭头只准向下:上面可以调下面的接口,下面不准认识 HTTP、不准倒依赖 Controller。换数据库或换通知渠道,只改基础设施。

L1接入层 Interface

HTTP 路由、登录态、参数校验、错误码映射。不写业务 if。组件:LoanControllerAuthFilter

↓ 只传命令 / 查询对象,不传 HttpRequest

L2应用层 Application

一个用例一个服务:ApplyLoanApproveLoanCheckoutLoanReturnLoan。编排事务与通知,不塞领域规则。

↓ 调用聚合与领域服务,不拼 SQL

L3领域层 Domain

聚合 LoanOrderDevice;规则「在库才能批准」「已借出才能归还」。状态机只活在这里。仓储接口在本层定义,实现不在本层。

↓ 通过接口访问外部,领域不 import 驱动

L4基础设施层 Infrastructure

PgLoanRepositoryPgDeviceRepositoryMailNotifierStaffDirectoryClient。SQL、SMTP、LDAP 只出现在这一层。

接入 应用 领域 基础设施 只允许向下
图 2 分层:依赖单向向下;领域定义仓储接口,基础设施来实现

包结构按层落盘,避免「一个 utils 兜住所有」:

deviceloan/
  interface/http/          # L1
  application/             # L2  用例
  domain/
    model/                 # L3  聚合、值对象
    service/               # L3  跨聚合规则(如库存占用)
    port/                  # L3  Repository / Notifier 接口
  infrastructure/
    persistence/           # L4
    notify/                # L4
    directory/             # L4

层间禁令: Controller 不得 new 出 SQL;LoanOrder 不得引用 Spring / Gin 注解以外的 Web 类型;通知失败不能回滚已经成立的领域状态——由应用层记补偿任务。

11.6 请求如何穿过各层

以「管理员批准借单」为例。成功与失败都要看见停在哪一层。

管理员 L1 接入 L2 应用 L3 领域 L4 仓储 POST /loans/7/approve ApproveLoan(7, admin) load Order + Device order.approve(device) 同一事务 save 200 或 409 设备已占用 → 领域拒绝
生命线 = 一层 HTTP 命令 / 仓储 领域方法 返回 领域拒绝
图 3 批准:L1 只转命令;占用冲突在 L3 判定,L1 映射为 409

失败不写在 Controller 里「再查一次库存」。领域返回 DeviceNotAvailable,接入层翻译成 HTTP。这样换 gRPC 时,规则不用搬家。

11.7 领域状态机

借单状态只由领域方法推进。应用层调用 approve / checkout / giveBack,不得直接 SET status=

submitted approved borrowed returned Approve Checkout Return Reject(终态) Cancel
状态 领域事件 Reject(终态) Cancel
图 4 借单:Approve / Checkout / Return;Reject、Cancel 为结束。事件在领域方法上

设备侧另有两态:availableon_loan。批准时占用,归还时释放。两边必须同一事务提交,避免「单过了、库存没占上」。

11.8 数据与接口

权威在 PostgreSQL。devices.asset_no 唯一;loan_ordersloan_items 表达一张单可借多件(本期限制 1 件,表仍按多件留)。无 Redis 热点,读走主库。

接口(接入层)用例(应用层)失败
POST /v1/loans 登录员工
{"asset_no":"EQ-012","days":3}
ApplyLoan 设备不存在 404;已占用 409 DEVICE_ON_LOAN
POST /v1/loans/{id}/approve 管理员 ApproveLoan 非 submitted 409;库存被别人截胡 409
POST /v1/loans/{id}/return 管理员 ReturnLoan 非 borrowed 409

幂等:ApplyLoan 使用 Idempotency-Key,同一员工 24 小时内相同 Key 返回同一借单。审批不幂等重放成第二次占用——重复 Approve 对已 approved 返回 200 且不改数据。

11.9 取舍、风险与发布

为什么分层而不是单文件 CRUD? 审批规则已经出现「周末是否计入租期」「管理员不能批给自己」——这些会涨。放进 Controller 三个月后就会复制到脚本和定时任务里各写一份。

为什么不先上工作流引擎? 现在只有单级审批。引擎引入状态外置,领域图反而看不清。第二级审批出现时再抽 ApprovalPolicy

风险: 批准与占库的竞态——同一设备两张 submitted 单,用设备行 SELECT FOR UPDATE 串行化。通知失败: 领域提交成功后应用层写 outbox,定时投递,不回滚借单。

观测: loan_approve_total{result}device_on_loan_gaugeoverdue_notice_failed。逾期任务连续失败 3 次告警。

发布: 先行政 3 人试用一周,开关 deviceloan.enabled。关闭后写入接口 503,已借出单据仍可归还。表格并行双写三天,对账无误再停表。

开放问题: 逾期是否自动续期 1 天——行政 @王五 本周四前回复。答案进来后只改领域规则,不改接入层。

对照本文前面的标准:读者能画出四层、能指出规则在领域、能按用例写第一行代码。图负责结构,表负责失败码,禁令负责防止分层塌回大泥球。


12. 动笔前的检查清单

写完或评审前,按表勾一遍。未勾的项,就是读者会卡住的地方。


13. 常见跑偏,以及对一下

跑偏 看起来像 改法
小说 从项目成立写到今天 背景最多一节,其余进附录
代码说明书 大段伪代码,没有决策 决策上移,代码放到 LLD
幻灯片 全是标题和形容词 每节补上数字、接口、失败
日记 按讨论时间罗列发言 按问题重组,发言进会议纪要
百科 一篇覆盖构建、部署、UI、薪酬 拆文档,互相链接
秘密 关键数字只在会上说 写进正文,否则等于没设计

收束

写出漂亮、好懂的设计文档,靠的不是文采,而是对读者的体贴:先告诉他要做什么决定,再给他刚好够用的结构、图和数字;把形容词换成机制,把情绪换成取舍,把「以后再说」写成非目标或开放问题。

你可以记住一句更短的标准:

一个没参加讨论的同事,只读这一篇,能画出系统、能指出风险、能开始写第一行代码——这才叫写完了。

从下一篇起,先写摘要和非目标,再画一张失败路径图。文档多半会立刻好看一截。