1. 从一张草图到一套系统:diagram-design 到底在解决什么问题
第一次看到“diagram-design”这个标题,很多人会以为它只是教你怎么画流程图、时序图或者架构图。但真正做过技术方案、写过设计文档、给团队做过架构评审的人都知道,画图这件事从来不是“画得好看”这么简单。它背后牵扯的是一整套信息表达体系:你要把脑子里模糊的结构变成别人能看懂的图形,要把复杂的调用链路压缩成一张不丢关键信息的拓扑,还要让不同角色——开发、产品、运维、管理层——在同一张图上找到各自关心的部分。
diagram-design 这个项目,核心就是围绕“图的设计”来做文章。它不是某个具体工具的教程,也不是单纯的设计规范合集,而是一套从需求拆解、图形选型、布局规划到最终落地的完整方法论。说得再直白一点,它解决的是“脑子里有结构,但画出来就乱”的问题。适合谁来参考?我认为三类人最需要:第一类是经常写技术方案但图总被吐槽“看不懂”的后端或架构同学;第二类是需要用图来对齐需求、但缺乏制图训练的产品经理;第三类是做技术写作、文档维护、知识库建设的同学,你们可能每天都在和图打交道,但很少系统想过“为什么这张图要这样画”。
我自己的经历比较典型。早些年做微服务改造,画了一张服务依赖图,自认为逻辑清晰,结果评审会上被问了三个问题:数据流在哪、同步调用和异步消息怎么区分、故障域边界在哪里。那张图当时就挂了。后来我才意识到,图不是“把框和线摆上去”,而是“把决策信息编码进视觉元素”。diagram-design 的价值就在于,它把这种编码规则讲透了,让你画出来的图不只是“能看”,而是“能用来做判断”。
这篇文章我会按照实际做项目的思路来拆:先讲整体设计思路和选型逻辑,再拆核心细节和实操要点,然后给出一套可以直接抄的落地流程,最后把我踩过的坑和排查技巧整理出来。全文没有平台痕迹,也不涉及任何敏感内容,就是一份从业者的项目总结。你可以把它当成一个“图设计”的参考手册,也可以当成下次画图前的检查清单。
2. 整体设计思路与方案选型:为什么图不能随便画
2.1 先定“图的目的”,再定“图的类型”
很多人画图的第一步是打开工具,第二步是拖框,第三步是连线,第四步是调颜色。这个顺序是反的。diagram-design 的第一个原则就是:先明确这张图要回答什么问题,再决定用什么图。
我习惯把图的目的分成四类:
- 解释结构:比如系统分层、模块划分、部署拓扑。这类图的核心是“边界”和“归属”,适合用分层图、包图、部署图。
- 解释流程:比如请求链路、审批流、数据加工流程。这类图的核心是“顺序”和“分支”,适合用流程图、时序图、状态机图。
- 解释关系:比如服务依赖、数据表关联、组织协作。这类图的核心是“连接”和“强弱”,适合用依赖图、ER图、网络图。
- 解释变化:比如版本演进、迁移阶段、状态流转。这类图的核心是“时间”和“条件”,适合用时间线图、状态迁移图。
为什么这个分类重要?因为不同类型的图,读者的阅读路径完全不同。结构图是从外往里看,流程图是从左往右看,关系图是从中心往四周看。如果你用流程图的布局去画结构图,读者就会不自觉地找“起点”和“终点”,结果发现找不到,认知负荷立刻上升。
我见过一个典型的反例:某团队用泳道图去画微服务架构,把每个服务放在一个泳道里,然后用箭头表示调用。看起来很美,但读者会误以为箭头代表时间顺序,实际上那是同步调用和异步消息混在一起。后来改成分层依赖图,把同步调用用实线、异步消息用虚线、数据存储用圆柱体,评审效率立刻提升。这就是 diagram-design 里说的“图形语义一致性”。
2.2 工具选型:不是越强大越好,而是越合适越稳
关于工具,我的观点可能和很多人不一样:工具选型的第一原则不是功能多,而是“团队里大多数人能改”。你画得再漂亮,别人改不了,这张图就是死的。
常见的图设计工具大致分几类:
| 工具类型 | 代表形态 | 适合场景 | 主要风险 |
|---|---|---|---|
| 代码化绘图 | 文本描述生成图 | 需要版本管理、频繁迭代 | 学习曲线陡,样式调整不直观 |
| 拖拽式绘图 | 画布工具 | 一次性汇报、视觉要求高 | 难以协作,容易变成“图片孤岛” |
| 文档内嵌绘图 | 文档平台自带 | 轻量说明、快速对齐 | 复杂布局能力弱 |
| 白板协作绘图 | 在线白板 | 头脑风暴、远程评审 | 结构容易散,后期难维护 |
我自己的选择策略是:长期维护的图用代码化,一次性汇报的图用拖拽式,评审讨论的图用白板,最终归档的图回到代码化。为什么?因为代码化绘图天然适合版本管理,你可以把图当成代码来 review,diff 里能看出这次改了哪个节点、哪条边。拖拽式工具虽然上手快,但改三次之后,你自己都忘了哪个版本是最新的。
这里有个细节:代码化绘图工具通常支持“自动布局”,但自动布局不是万能的。我试过用自动布局画一张二十多个节点的依赖图,结果线交叉得一塌糊涂。后来我手动调整了节点分组和方向约束,才把交叉降到可接受范围。所以我的经验是:自动布局用来打底,手动约束用来收尾。不要指望一键生成完美布局,那和指望自动排版出一本画册一样不现实。
2.3 视觉编码:颜色、形状、线型不是装饰,是信息
diagram-design 里最容易被忽略、但最重要的一部分,就是视觉编码。很多人把颜色当装饰,把形状当习惯,把线型当默认。实际上,每一个视觉元素都应该承载信息。
我通常遵循这套编码规则:
- 形状:矩形代表服务或模块,圆柱代表数据存储,菱形代表决策点,圆角矩形代表外部系统,云形代表第三方依赖。
- 颜色:冷色代表内部组件,暖色代表外部依赖,灰色代表已废弃或待迁移,红色代表风险点或故障域。
- 线型:实线代表同步调用,虚线代表异步消息,点线代表数据流,粗线代表高频或关键路径。
- 方向:从左到右代表请求方向,从上到下代表依赖方向,双向箭头只在真正双向依赖时使用。
为什么要有这套规则?因为读者的短期记忆有限。如果同一张图里,红色一会儿代表风险,一会儿代表数据库,读者就会混乱。编码一致性带来的好处是:读者看第一眼时在学习规则,看第二眼时就能直接读信息。这就像交通标志,你不需要每次看到红灯都重新理解一遍。
注意:颜色编码不要超过五种。超过五种之后,读者需要频繁回看图例,阅读体验会急剧下降。如果信息维度确实多,宁可拆成两张图,也不要在一张图里堆颜色。
2.4 布局规划:让读者的眼睛少走路
布局这件事,很多人觉得是“审美问题”,其实它是“认知效率问题”。一张图的布局好坏,直接决定读者需要花多少时间找到关键信息。
我常用的布局策略有三种:
- 分层布局:适合结构图。上层是接入层,中层是业务层,下层是数据层。每层内部从左到右排列,层与层之间用短箭头连接。这样读者的视线是“上下扫描”,符合阅读习惯。
- 中心辐射布局:适合关系图。把核心服务放在中心,依赖它的服务放在外围,用不同颜色区分调用方向。这样读者一眼就能看出“谁依赖谁”。
- 泳道布局:适合流程图。按角色或系统分泳道,流程从左到右推进。泳道的好处是责任边界清晰,坏处是节点多了之后横向会拉得很长。
我踩过的一个坑是:把一张图塞得太满。当时为了“一张图讲清楚整个系统”,我把网关、服务、数据库、消息队列、缓存、第三方接口全画在一张图上,结果打印出来是 A3 纸,字小到看不清。后来拆成三张:一张总览、一张核心链路、一张数据流向。每张图只回答一个问题,评审时反而更高效。
所以布局的核心原则是:一张图只讲一个故事。如果故事讲不完,就分章节。图不是越全越好,而是越清晰越好。
3. 核心细节解析与实操要点:从需求到成图的完整拆解
3.1 需求拆解:先写“图的大纲”,再动手画
我现在的习惯是,画图之前先写一段文字大纲。这段大纲不是给别人看的,是给自己理思路的。大纲通常包含四个问题:
- 这张图的目标读者是谁?
- 他们看完这张图需要做出什么判断?
- 图里必须出现哪些元素?
- 哪些元素可以省略?
举个例子,如果目标读者是运维同学,他们关心的是部署单元、网络边界、故障域、监控点。那么图里就必须有节点分组、网络区域、冗余标识。如果目标读者是产品经理,他们关心的是功能模块和用户路径,那么技术细节就可以省略。
这个步骤看起来简单,但能避免大量返工。我见过太多人画完图才发现“读者根本不关心这些细节”,然后重新画。先写大纲,相当于先做信息架构,再做成图。
3.2 节点设计:一个节点只表达一件事
节点是图的基本单元。diagram-design 里强调一个原则:一个节点只表达一件事。不要把“用户服务”和“用户数据库”画在一个框里,也不要把“认证”和“授权”合并成一个节点。
为什么?因为节点一旦合并,连线就会变得模糊。比如“认证授权服务”连到“用户服务”,读者不知道是认证调用用户服务,还是授权调用用户服务。拆开之后,每条线的语义就清晰了。
节点的命名也有讲究。我通常用“名词+角色”的格式,比如“订单服务”“支付网关”“消息队列”“配置中心”。避免用“模块A”“系统B”这种无意义命名。如果节点是外部系统,我会加一个前缀,比如“外部-支付渠道”“外部-短信平台”,这样读者一眼就能区分内外。
还有一个细节:节点的粒度要一致。如果一张图里,有的节点是“服务”,有的节点是“接口”,有的节点是“数据库表”,读者就会混乱。要么全用服务粒度,要么全用接口粒度,不要混。
3.3 连线设计:箭头方向就是依赖方向
连线是图里最容易出错的地方。我总结了几条规则:
- 箭头方向代表依赖方向,不是数据流向。如果 A 调用 B,箭头从 A 指向 B。如果数据从 B 返回 A,不需要画反向箭头,除非返回数据本身是另一个独立流程。
- 同步调用用实线,异步消息用虚线。这个区分非常重要,因为同步调用会阻塞,异步消息不会。运维同学看到实线,就知道这里需要关注超时和熔断;看到虚线,就知道这里需要关注积压和重试。
- 避免交叉线。如果两条线必须交叉,尽量用“跳线”符号,或者调整节点位置。交叉线是阅读障碍,能少则少。
- 标注关键信息。比如调用协议、数据格式、频率。但不要标注太多,否则图会变成文字堆砌。我通常只标注“非默认”的信息,比如“HTTP/2”“Protobuf”“每秒万次”。
提示:如果一张图里连线超过三十条,考虑拆图。人的短期记忆大概能同时处理五到七条线,超过之后就需要频繁回看,效率会下降。
3.4 图例与注释:让图自己解释自己
图例不是可有可无的装饰。一张没有图例的图,读者需要猜你的颜色和线型含义。我通常在图的一角放一个简洁的图例,包含:
- 形状含义(矩形、圆柱、菱形等)
- 颜色含义(内部、外部、风险等)
- 线型含义(同步、异步、数据流等)
注释则用来解释“为什么这样设计”。比如某个节点旁边加一个注释:“此处引入缓存是为了降低数据库压力,命中率约 85%。”这种注释能让图从“描述现状”升级为“解释决策”。
但注释不要太多。如果每个节点都加注释,图就变成了文档。我的经验是:只注释那些“读者可能会问为什么”的地方。比如为什么这里要加消息队列,为什么这个服务要独立部署,为什么这条链路是异步的。
3.5 版本管理:图也要有 changelog
这一点很多人忽略。图是会变的,尤其是架构图。如果没有版本管理,三个月后你根本不知道这张图对应的是哪个版本的系统。
我的做法是:图文件旁边放一个简短的 changelog,记录每次修改的时间、修改人、修改内容。如果是代码化绘图,直接看 git log 就行。如果是拖拽式工具,至少在图的下方加一行“最后更新:某年某月某日,更新内容:新增支付服务”。
为什么这个重要?因为图是沟通工具。如果图和系统不一致,沟通就会变成误导。我见过一次事故复盘,用的架构图是半年前的版本,结果讨论了半天才发现图里少了一个关键服务。这种坑,一次就够了。
4. 实操过程与核心环节实现:一套可以直接抄的落地流程
4.1 第一步:明确目标与读者,写出图的大纲
假设我们要画一张“订单系统架构图”,目标读者是研发和运维,目的是评审新订单链路的可靠性。那么大纲可以这样写:
- 目标读者:后端研发、运维、测试
- 需要回答的问题:订单创建链路经过哪些服务?哪些是同步调用?哪些是异步消息?故障域在哪里?
- 必须出现的元素:订单服务、支付服务、库存服务、消息队列、数据库、缓存、网关
- 可以省略的元素:具体接口名、字段名、内部类结构
写完大纲之后,我会先画一个草图,用纸笔或者白板。草图不追求好看,只追求逻辑完整。这个阶段最重要的是“把脑子里的结构倒出来”,而不是“画得漂亮”。
4.2 第二步:选择图形类型与布局方式
根据大纲,这张图的核心是“链路”和“依赖”,所以我选择分层依赖图,布局采用从左到右的请求方向,同时用上下分层区分接入层、业务层、数据层。
具体布局:
- 最左侧:网关和负载均衡
- 中间偏左:订单服务、支付服务、库存服务
- 中间偏右:消息队列、缓存
- 最右侧:数据库、外部支付渠道
同步调用用实线,异步消息用虚线。支付服务到外部支付渠道用虚线加锁图标,表示需要关注外部依赖的稳定性。
4.3 第三步:定义视觉编码规则
在动手画之前,先定义好编码规则,并写在图例里:
| 视觉元素 | 含义 |
|---|---|
| 蓝色矩形 | 内部服务 |
| 灰色矩形 | 外部系统 |
| 圆柱体 | 数据库 |
| 虚线圆柱 | 缓存 |
| 实线箭头 | 同步调用 |
| 虚线箭头 | 异步消息 |
| 红色边框 | 高风险节点 |
| 粗线 | 关键路径 |
这套规则一旦定下来,整张图就统一了。读者不需要每次重新理解。
4.4 第四步:绘制初稿并做“信息完整性检查”
初稿画完之后,我会做一次检查,问自己几个问题:
- 每个节点是否只表达一件事?
- 每条线的方向是否代表依赖方向?
- 同步和异步是否区分清楚?
- 是否有交叉线?能否优化?
- 图例是否完整?
- 关键路径是否突出?
这个检查通常能发现 30% 左右的问题。比如我经常发现某个节点命名太模糊,或者某条线忘了标异步。
4.5 第五步:找一个人“试读”,收集反馈
图是给人看的,所以必须找人试读。我通常找一个不参与这个项目的同学,让他看图并复述他理解的内容。如果他复述的内容和我的设计意图一致,说明图是清晰的;如果他有疑问,说明图里有歧义。
试读的时候,我会特别关注三个问题:
- 他第一眼看哪里?
- 他有没有问“这个箭头是什么意思”?
- 他能不能说出关键路径?
这三个问题能暴露大部分设计缺陷。
4.6 第六步:定稿、归档、写 changelog
定稿之后,我会把图导出成两种格式:一种是矢量图,用于文档嵌入;一种是图片,用于快速预览。然后写 changelog,记录版本、日期、修改内容。
如果是代码化绘图,我会把源文件也归档,方便后续修改。如果是拖拽式工具,我会保留源文件,并注明使用的工具版本。
注意:不要只保存图片。图片是死的,源文件是活的。三个月后你要改图,没有源文件就只能重画。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 图太乱,读者找不到重点
这是最常见的问题。原因通常有三个:节点太多、连线太多、颜色太多。
排查思路:
- 先看节点数量。如果超过十五个,考虑拆图。
- 再看连线数量。如果超过三十条,考虑分层或分组。
- 最后看颜色数量。如果超过五种,考虑减少编码维度。
我的经验是:一张图的信息量,应该控制在读者三分钟内能理解的程度。超过三分钟,读者就会失去耐心。
5.2 图和系统不一致,导致误导
这个问题通常是因为图没有版本管理,或者更新不及时。
解决方法:
- 把图纳入版本管理,和代码一起 review。
- 每次系统变更时,同步更新图。
- 在图的下方标注“最后更新时间”和“对应系统版本”。
我自己的做法是:把架构图放在代码仓库的 docs 目录下,每次发版前检查是否需要更新。这样图就不会变成“历史文物”。
5.3 同步和异步混在一起,运维看不懂
这个问题很典型。很多图里,同步调用和异步消息用同一种线型,运维同学无法判断哪里需要关注超时,哪里需要关注积压。
解决方法很简单:同步用实线,异步用虚线。如果还有数据流,用点线。三种线型足够覆盖大部分场景。
如果一张图里同步和异步都很复杂,可以考虑拆成两张:一张同步链路图,一张异步消息图。
5.4 节点命名太抽象,读者需要猜
“服务A”“模块B”“系统C”这种命名,读者看完根本不知道是什么。好的命名应该让读者一眼就知道这个节点的职责。
我的命名规则:
- 内部服务:业务名+服务,如“订单服务”“库存服务”
- 外部系统:外部+业务名,如“外部-支付渠道”
- 数据存储:业务名+存储类型,如“订单数据库”“用户缓存”
- 中间件:中间件类型+用途,如“订单消息队列”
5.5 图例缺失,读者靠猜
图例是图的“说明书”。没有图例,读者就需要猜颜色和线型的含义。猜对了还好,猜错了就会产生误解。
我的做法是:每张图都必须有图例。图例放在图的右下角或左下角,不要太大,但要完整。如果图里用了特殊符号,比如锁图标、警告图标,也要在图例里说明。
5.6 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决建议 |
|---|---|---|---|
| 图太乱 | 节点/连线/颜色过多 | 统计数量 | 拆图或减少编码维度 |
| 读者找不到重点 | 关键路径不突出 | 找人试读 | 用粗线或颜色突出关键路径 |
| 图和系统不一致 | 缺少版本管理 | 对比系统文档 | 纳入版本管理,定期更新 |
| 同步异步混淆 | 线型未区分 | 检查图例 | 实线同步,虚线异步 |
| 节点命名模糊 | 命名太抽象 | 让读者复述 | 用业务名+角色命名 |
| 图例缺失 | 忽略图例 | 检查图角落 | 每张图必须加图例 |
5.7 独家避坑技巧
第一个技巧:画图之前先写文字大纲。这个习惯能帮你省下大量返工时间。文字大纲不需要很详细,但必须回答“读者是谁、要回答什么问题、必须出现什么、可以省略什么”。
第二个技巧:找非项目成员试读。项目成员因为熟悉系统,会自动脑补缺失信息。非项目成员没有这个背景,他们的疑问才是真实读者的疑问。
第三个技巧:图不要超过三分钟阅读量。如果一张图需要超过三分钟才能理解,就拆成两张。宁可多画一张,也不要让读者在一张图里迷路。
第四个技巧:颜色不要超过五种。超过五种之后,读者需要频繁回看图例,阅读效率会下降。如果信息维度确实多,用形状或线型来补充,不要全堆在颜色上。
第五个技巧:图例要放在读者视线自然停留的位置。通常右下角或左下角比较合适。不要放在顶部,因为读者看图的起点通常是左上角或中心。
6. 图设计之后的延伸:从单张图到图体系
画好一张图只是开始。真正有价值的,是把图组织成一个体系。我现在的做法是:每个系统维护一套图,包括总览图、核心链路图、数据流向图、部署图。每张图回答不同的问题,但共享同一套视觉编码规则。
这样做的好处是:读者看第一张图时学习规则,看后续图时就能直接读信息。整个图体系的认知成本会大幅降低。
另外,图不是画完就结束了。每次系统变更、每次评审反馈、每次故障复盘,都是更新图的时机。图是活的,不是死的。我见过最好的图,是那种“看一眼就知道系统当前状态”的图。这种图不是一次画出来的,是持续维护出来的。
如果你刚开始做 diagram-design,我的建议是:先从一张图开始,把规则定好,把图例加上,找人试读,然后迭代。不要追求一次完美,追求每次都比上次清晰一点。画图这件事,和写代码一样,是练出来的。