1. 从“diagram-design”这个标题说起:它到底在解决什么问题
第一次看到“diagram-design”这个标题,很多人会下意识觉得它是个设计工具或者某个绘图库的名字。但如果你真的动手做过技术方案、写过架构文档、或者给团队做过知识沉淀,就会明白这个标题背后藏着的其实是一个更本质的痛点:图不是画不出来,而是画完之后没人看得懂、没人愿意维护、过两周连自己都认不出来。
我见过太多项目里的架构图,画的时候花了两小时,评审的时候被问了八个问题,改完之后就再也没人打开过。问题出在哪?不是工具不好用,而是画图这件事从一开始就缺少一套“设计”的思路。大家把画图当成了“把脑子里的东西倒出来”的动作,而不是“把信息重新组织给读者看”的设计过程。
“diagram-design”这个标题,我理解它指向的核心是:用设计的思维去对待每一张图,让图本身成为一种可读、可维护、可传递的信息载体。它可能是一个内部工具、一套绘图规范、一个基于代码生成图表的方案,也可能是一个帮助团队统一图形语言的实践项目。不管具体形态是什么,它要解决的问题是共通的——降低图的阅读成本,提高图的存活周期。
这篇文章适合谁看?如果你是那个在项目里负责画架构图、流程图、时序图、状态机图的人,或者你正在被“图太多、太乱、没人看”这件事困扰,那接下来的内容应该能帮到你。我会从图的本质、设计原则、工具选型、实操步骤、常见坑这几个角度,把“diagram-design”这件事拆开讲透。
2. 图的本质不是“画”,而是“信息压缩与再表达”
2.1 为什么大多数技术图活不过一个迭代
先问一个扎心的问题:你上一次认真看别人画的架构图是什么时候?如果那张图超过三个月没更新,你还会信它吗?
大多数技术图的生命周期短得可怜,根本原因在于它们被当成了“一次性交付物”。画图的人当时的认知是完整的,所以他画出来的图是“给自己看的备忘录”,而不是“给未来的人看的说明书”。一旦画图的人离开或者记忆模糊,这张图就变成了一个没有注释的密码本。
我观察下来,一张图活不长的原因通常有三个:
- 信息密度失控:一张图里塞了二十个模块、三十条连线,读者第一眼就放弃了。
- 抽象层级混乱:数据库表结构和业务领域模型画在同一张图里,读者不知道该关注哪一层。
- 缺少更新机制:图是手工画的,代码改了图没改,久而久之图就成了“历史文物”。
“diagram-design”要做的第一件事,就是承认图是有生命周期的,并且从设计之初就为它的维护和更新留出空间。
2.2 一张好图的三个硬指标
那什么样的图算是“设计过”的图?我自己的判断标准有三个,缺一不可:
第一,三秒内能看出主题。读者扫一眼就知道这张图在讲什么,是部署架构、是数据流、还是状态流转。这要求图的标题、图例、主视觉区域足够明确,不需要读者去猜。
第二,三十秒内能找到关键路径。如果这是一张流程图,读者应该能快速定位到主流程;如果是架构图,应该能一眼看出核心服务和边缘依赖。这意味着图里要有视觉层次,重要的东西要突出,次要的东西要弱化。
第三,三分钟内能理解细节。当读者决定深入看的时候,图里的标注、分组、连线说明应该足够支撑他理解具体逻辑。这要求图不是“一坨”,而是有清晰的分区和注释。
这三个指标听起来简单,但真正能做到的图少之又少。大部分图卡在第一步——读者看了三秒还不知道这张图想表达什么。
2.3 从“画图”到“设计图”的思维转变
“画图”和“设计图”的区别,有点像“写字”和“排版”的区别。写字是把想法落到纸上,排版是考虑读者怎么读最舒服。
画图的时候,你的关注点是“我要把我知道的都放上去”。设计图的时候,你的关注点变成“读者需要按什么顺序、什么粒度来接收这些信息”。
这个转变会直接影响你的操作:
- 你会开始考虑分区:把相关的元素放在一起,用背景色或者边框框起来。
- 你会开始考虑流向:读者的视线应该从左到右、从上到下,还是按照某个环形路径移动。
- 你会开始考虑省略:哪些细节可以放到附注里,哪些可以干脆不画,只保留主干。
- 你会开始考虑一致性:同样的形状代表同样的含义,同样的颜色代表同样的状态。
这些考虑,才是“diagram-design”里“design”这个词的真正含义。
3. 工具选型:为什么我不推荐一上来就打开拖拽式绘图软件
3.1 拖拽式工具的甜蜜陷阱
几乎所有人画图的第一反应都是打开某个拖拽式绘图工具,然后开始从左侧图库里拖方框、拖箭头。这种方式上手极快,五分钟就能画出一张“看起来像那么回事”的图。
但拖拽式工具有一个致命的陷阱:它鼓励你一次性画完,而不是迭代修改。当你花了一个小时调整方框的位置、对齐箭头、配色,结果评审时被告知“这个模块要拆成两个”,你的第一反应是抗拒——因为改起来太麻烦了。于是你选择在图上打个补丁,而不是重新组织结构。图就这样一步步走向混乱。
另一个问题是,拖拽式工具产出的文件通常是二进制格式,没法做版本对比。你改了哪里、为什么改,全靠 commit message 里那几句描述。时间一长,图的历史就丢失了。
3.2 代码化绘图:让图变成可 diff 的文本
“diagram-design”这个标题如果让我来落地,我会优先考虑代码化绘图的方案。所谓代码化绘图,就是用文本描述图的结构,然后由渲染引擎生成图片。常见的方案包括基于 DSL 的绘图工具、用 Markdown 扩展语法描述流程图、或者用编程语言的绘图库直接生成。
代码化绘图的好处非常明显:
- 可版本控制:图变成了纯文本,git diff 能清楚看到每次改了什么。
- 可复用:公共的样式、图例、模块定义可以抽出来共享。
- 可自动化:图可以跟着代码一起生成,代码改了图自动更新。
- 可评审:图的改动可以像代码一样走 pull request 流程。
当然,代码化绘图也有代价:学习成本比拖拽高,初期画图速度慢,复杂布局的微调不如拖拽灵活。但从长期维护的角度看,这个投入是值得的。
3.3 选型对比:不同场景下的合理选择
我把常见的几种绘图方式做了一个对比,你可以根据自己的场景来选:
| 方案类型 | 适合场景 | 维护成本 | 上手难度 | 版本控制友好度 |
|---|---|---|---|---|
| 拖拽式绘图工具 | 一次性演示、对外汇报 | 高 | 低 | 差 |
| 代码化 DSL 绘图 | 架构图、流程图、长期维护 | 低 | 中 | 好 |
| 编程语言绘图库 | 数据驱动图表、自动化报告 | 低 | 高 | 好 |
| 手绘风格工具 | 头脑风暴、早期设计 | 中 | 低 | 中 |
我的建议是:如果这张图的预期寿命超过两周,或者需要多人协作维护,就优先考虑代码化方案。如果只是一次性的汇报材料,拖拽式工具也没什么不好。
注意:不要为了“看起来专业”而强行上代码化方案。如果团队里没人愿意维护文本描述,那代码化绘图反而会成为负担。工具是为人服务的,不是反过来。
4. 实操:用代码化思路设计一张可维护的架构图
4.1 第一步:先写“图的提纲”,而不是先画框
很多人画图的第一步是打开工具,然后开始拖方框。我的习惯是反过来的:先在纸上或者文档里写这张图的提纲。
提纲的内容包括:
- 这张图的主题是什么?一句话说清楚。
- 读者是谁?是开发、运维、还是产品?
- 图里要出现哪些核心元素?列一个清单。
- 这些元素之间的关系是什么?谁调用谁、谁依赖谁、谁流向谁。
- 哪些细节是必须画的,哪些是可以省略的?
这个提纲写下来,通常就是十几行文字。但它能帮你在动手之前就想清楚图的结构,避免画到一半发现“这个模块放哪里都不对”。
4.2 第二步:定义图的“词汇表”
提纲写完之后,下一步是定义这张图的“词汇表”。所谓词汇表,就是规定图里每种形状、每种颜色、每种连线代表什么含义。
比如:
- 圆角矩形代表服务
- 直角矩形代表数据库
- 虚线箭头代表异步消息
- 实线箭头代表同步调用
- 红色代表已废弃
- 绿色代表新增
这个词汇表不需要很复杂,但一定要在画图之前定下来,并且在同一张图里保持一致。我见过太多图,同一个含义用了三种不同的形状,读者根本分不清。
如果团队里有多个画图的人,这个词汇表最好能沉淀成一份共享的规范文档。这样大家画出来的图风格统一,读者不需要每次重新学习图例。
4.3 第三步:用文本描述图的结构
假设我们选择了一种基于文本的绘图方案,那么接下来就是把提纲翻译成具体的描述。以一张典型的微服务架构图为例,描述大概长这样:
系统边界: 订单系统 服务: - 订单服务 (核心) - 支付服务 (核心) - 库存服务 (核心) - 通知服务 (边缘) 数据库: - 订单库 (主) - 支付库 (主) 外部依赖: - 消息队列 - 缓存集群 关系: - 订单服务 -> 订单库: 读写 - 订单服务 -> 支付服务: 同步调用 - 订单服务 -> 消息队列: 发送事件 - 支付服务 -> 支付库: 读写 - 库存服务 -> 消息队列: 订阅事件 - 通知服务 -> 消息队列: 订阅事件这段描述本身不是图,但它包含了图的所有结构信息。渲染引擎可以根据这段描述自动生成布局,你不需要手动调整每个方框的位置。
4.4 第四步:渲染、评审、迭代
描述写完之后,渲染成图,然后拿给同事看。重点问三个问题:
- 你能看出这张图的主题吗?
- 你能找到主流程吗?
- 有没有哪个地方让你困惑?
根据反馈调整描述,重新渲染。因为图是代码生成的,调整的成本很低,你可以快速迭代好几轮。
这个过程和写代码很像:先写草稿,再 review,再修改。图的“设计”就体现在这个迭代过程中,而不是一次成型的“大作”。
4.5 第五步:把图接入自动化流程
如果这张图描述的是系统架构,那它最好能跟代码仓库放在一起。每次架构有变动,对应的描述文件也跟着改,CI 流程里可以加一步自动渲染,确保图永远是最新的。
更进一步,如果图里的某些信息可以从代码或者配置里自动提取,那就更好了。比如服务的依赖关系可以从服务注册中心拉取,数据库表结构可以从 schema 文件生成。这样图就不再是“手工维护的文档”,而是“自动生成的视图”。
5. 设计一张图时最容易踩的五个坑
5.1 坑一:把图当成“全景照片”
新手画架构图,总想把所有东西都画进去。结果就是一张图里出现了五十个方框、八十条连线,读者看一眼就头晕。
正确的做法是分层。一张图只讲一个层级的事情。如果要展示全局,就画一张高层概览图,每个模块只用一个方框表示。如果要展示某个模块的内部,就单独画一张详细图。图与图之间用链接或者编号关联。
我自己的习惯是:任何一张图,方框数量不超过十五个,连线数量不超过二十条。超过这个数,就说明该拆图了。
5.2 坑二:连线没有方向或者方向混乱
箭头是图里最重要的信息载体之一,但很多人画箭头很随意。有的箭头表示调用,有的表示数据流,有的表示依赖,但图上没有任何说明。
更糟糕的是方向混乱:A 指向 B,但实际是 B 调用 A。这种错误在评审时会被一眼看穿,但在自己画的时候很容易搞混。
我的建议是:每一条连线都要有明确的语义,并且在图例里写清楚。如果一条连线的方向不重要,那就用无向线,不要用箭头。
5.3 坑三:颜色用得太多太花
颜色是很好的信息编码工具,但滥用颜色会让图变得像调色盘。我见过一张图用了十几种颜色,结果读者根本记不住哪种颜色代表什么。
一个实用的原则是:一张图的主色调不超过三种,辅助色不超过两种。主色调用来区分大的分类,辅助色用来标注状态或者优先级。如果颜色不够用,说明你的分类维度太多了,应该考虑拆图。
另外,要考虑色盲读者的体验。红绿搭配是最常见的错误,因为红绿色盲人群很难区分。如果一定要用颜色编码,尽量选择亮度差异明显的颜色,或者同时用形状、纹理来辅助区分。
5.4 坑四:文字标注太小或者太密
图里的文字是为了帮助理解,但如果文字太小,读者需要放大才能看清,那就失去了意义。如果文字太密,读者会直接跳过。
我的经验是:图里的文字,正文字号至少要是图里最小方框高度的三分之一。如果放不下,就精简文字,把详细说明放到图外的附注里。
另外,文字的方向也要统一。横排的文字比竖排的好读,从左到右比从右到左好读。除非有特殊原因,否则不要旋转文字。
5.5 坑五:画完不检查就发布
这是最容易被忽视的坑。图渲染出来之后,一定要自己从头到尾看一遍,检查:
- 有没有拼写错误?
- 有没有连线穿过了方框?
- 有没有方框重叠?
- 图例和实际使用的形状是否一致?
- 标题和内容是否匹配?
这些检查花不了几分钟,但能避免很多尴尬。我见过太多图,发布之后被人指出“这个服务名字拼错了”,虽然是小问题,但会降低图的专业感。
6. 让图活得更久:维护与协作的实操经验
6.1 把图放在代码仓库里,而不是网盘里
图的存放位置直接决定了它的维护成本。如果图放在某个网盘或者在线文档里,那它和代码就是分离的。代码改了,没人会想起来去更新网盘里的图。
我的做法是:把图的描述文件放在代码仓库的docs/diagrams目录下,和代码一起走版本控制。每次代码有架构层面的改动,对应的图描述文件也应该在同一个 pull request 里更新。review 的时候,图和代码一起看,确保两者一致。
如果图是渲染出来的图片,可以把渲染脚本也放在仓库里,CI 流程里自动生成最新图片。这样仓库里永远有一份和代码同步的图。
6.2 给每张图加一个“最后更新日期”和“负责人”
图和人一样,需要有人对它负责。如果一张图没有明确的负责人,那它很快就会变成“孤儿图”,没人更新,也没人敢删。
我的习惯是在图的描述文件头部加一段元信息:
title: 订单系统架构图 owner: 某开发者 last_updated: 2025-01-15 related_code: src/order-service这样任何人看到这张图,都知道该找谁问问题,也知道这张图最后一次更新是什么时候。如果最后更新日期已经超过三个月,那读者就会对图的准确性打个问号。
6.3 定期做“图清理”
和代码一样,图也会积累技术债。有些图描述的系统已经下线了,有些图被新的图取代了,但它们还留在仓库里,造成混淆。
我建议每个季度做一次图清理:
- 列出仓库里所有的图描述文件。
- 逐个确认:这张图对应的系统还在吗?这张图还有人看吗?
- 如果系统已下线,把图移到
docs/diagrams/archive目录,并在文件头部标注“已归档”。 - 如果图被新图取代,直接删除旧图,并在新图里注明“取代了某某图”。
这个清理过程花不了多少时间,但能让仓库里的图保持“新鲜”,读者不会踩到过期的图。
6.4 用图来做沟通,而不是用图来做装饰
最后一条经验,也是最重要的一条:图是用来沟通的,不是用来装饰文档的。
我见过很多文档,开头放一张架构图,然后正文里再也不提这张图。读者看完图,再看正文,发现两者没什么关系。这种图就是装饰品,没有实际价值。
好的做法是:图出现在文档里,正文就要引用它。比如“如图 1 所示,订单服务通过消息队列与库存服务解耦”,这样图和正文就形成了呼应。读者看图的时候有上下文,看正文的时候有视觉参考。
如果一张图在文档里没有任何引用,那就要考虑它是不是必要的。也许删掉它,文档反而更清爽。
7. 从一张图到一套图形语言:团队层面的落地建议
7.1 先统一“图例”,再统一“工具”
很多团队在推行图形规范时,第一步是统一工具——“大家都用某某工具画图”。但工具统一了,画出来的图还是五花八门,因为每个人对“方框代表什么”“箭头代表什么”的理解不一样。
正确的顺序是:先统一图例,再统一工具。图例是语义层面的约定,工具是操作层面的选择。语义不统一,工具再统一也没用。
图例的制定不需要很复杂,一页纸就够了。核心是规定:
- 常见的元素类型(服务、数据库、队列、外部系统)用什么形状表示。
- 常见的关系类型(同步调用、异步消息、数据流、依赖)用什么线型表示。
- 常见的状态(正常、异常、废弃、新增)用什么颜色表示。
这份图例定下来之后,团队里所有人画图都参照它。新同学入职,第一件事就是看这份图例,然后就能看懂团队里所有的图。
7.2 建立“图评审”机制
图和人一样,需要 review 才能保证质量。我建议在团队里建立轻量级的图评审机制:
- 重要的架构图,在发布之前找至少一个同事看一眼。
- 评审的重点不是“画得好不好看”,而是“读者能不能看懂”。
- 评审意见要具体,比如“这个箭头方向反了”“这个模块缺少说明”,而不是“感觉有点乱”。
图评审不需要很正式,可以融入现有的代码评审流程。如果图描述文件和代码在同一个 pull request 里,那代码评审的时候顺便就把图看了。
7.3 沉淀“图模板”,降低画图门槛
如果团队里经常画某类图,比如微服务架构图、业务流程图、状态机图,那可以沉淀一些模板。模板里预置好常用的形状、颜色、布局,画图的人只需要填空就行。
模板的好处是降低门槛,让不擅长画图的人也能画出合格的图。同时,模板也保证了风格的一致性,读者不需要每次重新适应新的图例。
模板可以放在仓库的docs/diagrams/templates目录下,每个模板配一份简短的说明,讲清楚什么场景用哪个模板。
7.4 把图纳入“知识资产”管理
最后,图应该被当成团队的知识资产来管理,而不是一次性的工作产物。这意味着:
- 图有明确的负责人和更新机制。
- 图有版本历史,可以追溯变更。
- 图有分类和索引,方便查找。
- 图有生命周期,过期了要归档或删除。
当图变成知识资产,团队对它的态度就会不一样。大家会愿意花时间把图画好,因为知道这张图会被长期使用,而不是画完就扔。
8. 我个人的一些实操体会
说了这么多原则和方法,最后分享几个我在实际画图过程中总结的小技巧,都是踩过坑之后才明白的。
第一个技巧:先画草图,再上工具。不管用什么工具,我都会先用纸笔或者白板画一个草图。草图阶段只关注结构,不关注美观。结构定下来之后,再用工具去实现。这样能避免在工具里反复调整布局,浪费时间。
第二个技巧:把图发给一个“不了解背景”的人看。如果他能看懂,说明图是合格的。如果他看不懂,问他哪里看不懂,那个地方就是需要改进的。这个办法比自我检查有效得多,因为画图的人容易陷入“我知道所以别人也应该知道”的误区。
第三个技巧:图的标题要具体,不要用“系统架构图”这种泛泛的名字。改成“订单系统与支付系统的交互架构图”,读者一看就知道这张图的边界在哪里。标题越具体,读者的预期越准确。
第四个技巧:如果一张图改了三次还是觉得乱,那就推倒重来。有时候问题不是出在细节上,而是出在结构上。与其在乱图上修修补补,不如重新想一遍这张图到底要表达什么。推倒重来的成本,往往比修补更低。
第五个技巧:不要追求“一张图讲清楚所有事”。这是新手最容易犯的错误。一张图讲清楚一件事,就已经很成功了。剩下的内容,用第二张图、第三张图去讲。图与图之间用链接关联,形成一个图的网络,而不是一张巨无霸。
这些技巧没有什么高深的理论,都是实际操作中积累下来的。如果你也在做“diagram-design”相关的事情,希望这些经验能帮你少走一些弯路。图这件事,说到底是为沟通服务的。只要读者能看懂、愿意看、看得下去,你的图就是成功的。