1. 从一张草图到一套视觉语言:diagram-design 到底在解决什么问题
很多人第一次听到 diagram-design 这个词,会下意识觉得它只是“画流程图”。但真正做过技术方案、写过设计文档、给团队做过架构评审的人都清楚,图这件事远不止“画出来”那么简单。一张好的架构图,能让评审会上的人三分钟抓住重点;一张糟糕的图,能让原本清晰的逻辑变得比代码还难读。diagram-design 要解决的,恰恰是后者——它关注的不是“能不能画”,而是“画出来之后别人能不能看懂、能不能复用、能不能维护”。
我接触 diagram-design 这个概念,最早是因为团队里反复出现同一个问题:同一个系统,不同的人画出来的图完全不一样。有人用矩形表示服务,有人用圆角矩形;有人把数据库画成圆柱,有人直接写个“DB”塞在方框里;连线更是五花八门,实线、虚线、箭头、无箭头混着来。结果就是,每次新人接手,光理解图例就要花半天。diagram-design 的核心价值,就是把这套“各画各的”变成“有章可循”,让图从个人表达变成团队资产。
从更实际的角度看,diagram-design 适合三类人:第一类是技术文档写作者,需要把复杂系统用图讲清楚;第二类是架构师和技术负责人,需要在评审、汇报、交接场景下快速传递信息;第三类是产品经理和设计师,需要把流程、状态、关系可视化。它不要求你会写代码,也不要求你有美术功底,但它要求你理解“信息层级”和“视觉语法”这两个底层逻辑。说白了,diagram-design 是一门关于“如何用图形语言准确表达结构关系”的实践方法。
我见过太多人把时间花在调颜色、换字体、找图标上,最后图是好看了,但逻辑一团糟。diagram-design 的思路正好相反:先定结构,再定样式;先保证信息准确,再考虑视觉美观。这个顺序一旦搞反,返工成本极高。所以这篇文章不会一上来就教你用什么工具,而是先讲清楚 diagram-design 的底层逻辑,再一步步落到实操。
2. 图形语法的底层逻辑:为什么你的图别人看不懂
2.1 视觉编码与信息层级的对应关系
diagram-design 的第一性原理,是“视觉编码必须与信息层级一一对应”。什么意思?就是你在图里用的每一种视觉元素——形状、颜色、线条粗细、箭头方向——都应该承载明确且唯一的信息含义。如果同一个视觉元素在不同地方表示不同意思,读者就会困惑。
举个最常见的例子:很多人在画架构图时,用实线表示“调用关系”,用虚线表示“数据流向”,但同时又用虚线表示“异步消息”。这就冲突了。读者看到虚线,不知道到底是数据流还是异步消息。正确的做法是:线条样式只表示“关系类型”,如果要区分同步/异步,应该用箭头样式或线条颜色来区分,而不是复用同一种视觉通道。
我在实际项目中总结了一个简单的对应表,可以直接抄作业:
| 视觉元素 | 推荐承载的信息 | 禁止承载的信息 |
|---|---|---|
| 形状 | 组件类型(服务、数据库、队列、外部系统) | 组件重要性 |
| 颜色 | 所属域或层级(前端、后端、数据层) | 组件类型 |
| 线条样式 | 关系类型(调用、依赖、数据流) | 同步/异步 |
| 箭头 | 方向性(谁依赖谁、数据往哪流) | 关系类型 |
| 大小 | 相对规模或粒度 | 重要性 |
这张表的核心逻辑是:每个视觉通道只干一件事。形状管“是什么”,颜色管“属于哪”,线条管“怎么连”,箭头管“往哪走”。一旦你遵守这个规则,图的可读性会立刻提升一个档次。
2.2 为什么“好看”的图往往“难读”
这里有一个反直觉的结论:很多看起来漂亮的图,其实信息密度极低。我见过不少用专业设计工具做出来的架构图,配色高级、图标精致、阴影柔和,但你看完不知道系统有几个服务、谁调用谁、数据存哪里。原因很简单:设计者把精力放在了“视觉愉悦”上,而不是“信息传递”上。
diagram-design 强调一个原则:图的唯一目的是降低理解成本。任何增加理解成本的视觉元素,都应该被移除。阴影、渐变、3D 效果、装饰性图标,这些在营销物料里没问题,但在技术图里就是噪音。我个人的经验是,一张合格的 diagram-design 作品,应该做到“黑白打印出来依然能看懂”。如果你把颜色去掉就分不清组件类型,那说明你的视觉编码有问题。
还有一个常见误区是“图例越多越专业”。恰恰相反,好的 diagram-design 应该让读者不需要看图例就能理解。比如你用圆柱体表示数据库,这是行业通用约定,不需要额外说明;你用虚线框表示“外部系统”,这也是常见做法。但如果你自创了一套符号系统,那就必须配图例,而图例本身就是理解成本。
2.3 从“画图”到“设计图”的思维转变
大多数人画图的过程是:打开工具,拖几个框,连几条线,调调位置,完事。这是“画图”思维。diagram-design 要求的是“设计图”思维:先想清楚要表达什么信息,再选择最合适的视觉形式,最后才动手。
具体来说,动手之前先问自己三个问题:
- 这张图给谁看?给开发看,可以保留技术细节;给管理层看,必须抽象掉实现细节。
- 读者需要从图里获取什么信息?是系统边界、调用关系、数据流向,还是部署拓扑?不同目的对应不同的图类型。
- 信息层级是什么?哪些是核心组件,哪些是辅助组件?核心组件应该放在视觉中心,辅助组件放在边缘。
这三个问题回答清楚了,图的结构基本就定了。我见过太多人跳过这一步,直接开画,结果画到一半发现逻辑不对,推倒重来。花五分钟想清楚,能省半小时返工。
3. 从零搭建一套可复用的 diagram-design 规范
3.1 定义你的形状词汇表
任何一套 diagram-design 规范,第一步都是定义“形状词汇表”。所谓形状词汇表,就是规定每种组件类型用什么形状表示。这个表一旦定下来,团队所有人都要遵守,不能今天用矩形表示服务,明天用圆角矩形表示服务。
下面是我在一个中型项目里实际用过的形状词汇表,可以直接参考:
| 组件类型 | 形状 | 说明 |
|---|---|---|
| 服务/应用 | 圆角矩形 | 圆角半径统一,表示可独立部署单元 |
| 数据库 | 圆柱体 | 行业通用符号,无需图例 |
| 消息队列 | 六边形 | 区别于服务和数据库,表示异步通道 |
| 外部系统 | 虚线矩形 | 虚线表示边界之外,不受本系统控制 |
| 用户/角色 | 圆形 | 表示人,与系统组件区分 |
| 网关/代理 | 菱形 | 表示流量入口或转换点 |
这张表的关键在于“互斥性”:每种形状只对应一种组件类型,不能有歧义。比如圆角矩形和直角矩形如果同时存在,就必须有明确区分,否则读者会困惑。我建议形状种类控制在 6 种以内,太多了记不住。
另外,形状的尺寸也要有规范。我通常规定:核心服务宽度 160px,高度 80px;数据库宽度 120px,高度 80px;外部系统宽度 140px,高度 70px。统一尺寸的好处是,图看起来整齐,而且读者可以通过尺寸快速判断组件类型。
3.2 颜色不是装饰,是信息通道
在 diagram-design 里,颜色的唯一作用是“分组”。比如你用蓝色表示前端组件,绿色表示后端服务,橙色表示数据层,紫色表示外部依赖。这样读者一眼就能看出哪些组件属于同一层。
但颜色使用有三个铁律:
- 颜色数量不超过 5 种。超过 5 种,人眼就很难快速区分了。如果确实需要更多分组,用形状或边框样式来辅助。
- 颜色必须有一致的语义。蓝色永远表示前端,不能这张图表示前端,那张图表示数据库。
- 颜色不能是唯一区分手段。考虑到色盲用户和黑白打印场景,颜色必须配合形状或标签使用。
我个人的配色方案是:主色调用低饱和度色系,避免刺眼;背景用白色或浅灰;文字用深灰而不是纯黑,减少视觉疲劳。具体色值可以参考:前端 #4A90D9,后端 #5CB85C,数据层 #F0AD4E,外部系统 #9B9B9B。这套配色在投影仪和打印场景下都验证过,可读性不错。
3.3 连线规则:让关系一目了然
连线是 diagram-design 里最容易出问题的地方。我见过太多图,线条交叉、箭头混乱、实线虚线混用,读者根本追不下去。解决这个问题的核心是“连线规则”。
我的连线规则只有四条:
- 实线箭头:表示同步调用或直接依赖。箭头指向被调用方。
- 虚线箭头:表示异步消息或数据流。箭头指向数据流向。
- 无箭头实线:表示关联关系,没有方向性。比如两个服务共享同一个数据库。
- 线条颜色:与源组件颜色一致,方便追踪。
这四条规则覆盖了 90% 的场景。如果遇到特殊情况,比如双向调用,我建议用两条平行线分别表示,而不是用双向箭头。双向箭头在复杂图里很容易让人迷失方向。
还有一个细节:连线尽量避免交叉。如果两条线必须交叉,用“跳线”符号表示,而不是直接交叉。跳线就是在交叉处画一个小弧线,表示两条线不相连。这个细节虽小,但在复杂图里能大幅降低误读率。
3.4 布局原则:从左到右,从上到下
布局是 diagram-design 里最容易被忽视的部分。很多人画图是“哪里有空放哪里”,结果图看起来像打散的拼图。正确的做法是遵循“从左到右,从上到下”的阅读习惯。
具体来说:
- 水平方向表示流程:用户请求从左边进入,经过网关、服务、数据库,从右边输出。这样读者可以顺着视线追踪数据流。
- 垂直方向表示层级:上层是接入层,中层是业务层,下层是数据层。这样读者可以快速理解系统分层。
- 核心组件居中:最重要的服务放在图的正中央,辅助组件围绕四周。这样视觉焦点自然落在核心上。
我通常会用网格来辅助布局。比如把画布分成 12 列,每个组件占据 2-3 列,组件之间留 1 列间距。这样图看起来整齐,而且调整起来方便。网格不需要画出来,但心里要有。
4. 工具选型:不同场景下用什么画图
4.1 代码驱动 vs 拖拽式:怎么选
diagram-design 的工具大致分两类:代码驱动和拖拽式。代码驱动的代表是 PlantUML、Mermaid、Graphviz;拖拽式的代表是 draw.io、Excalidraw、Figma。
怎么选?我的经验是看“图的维护频率”。如果这张图需要频繁更新,比如系统架构图,每次加个服务都要改,那代码驱动更合适。因为代码可以版本控制,diff 清晰,改一行就能重新生成。如果这张图是一次性的,比如汇报用的示意图,那拖拽式更快。
但代码驱动有个门槛:你得学语法。PlantUML 和 Mermaid 的语法都不难,半天就能上手。我建议每个技术团队至少有一两个人掌握代码驱动工具,因为它在协作场景下优势太明显了。想象一下,两个人同时改一张拖拽式图,冲突了根本没法合并;但如果是代码,git merge 就能解决。
4.2 代码驱动工具的实操示例
以 Mermaid 为例,画一个简单的架构图:
graph LR User[用户] --> Gateway[网关] Gateway --> ServiceA[服务A] Gateway --> ServiceB[服务B] ServiceA --> DB[(数据库)] ServiceB --> Queue[消息队列] Queue --> Worker[异步处理器]这段代码生成的图,结构清晰,而且改起来极快。比如要加一个服务C,只需要加两行:
Gateway --> ServiceC[服务C] ServiceC --> DB重新渲染,图就更新了。这种效率是拖拽式工具比不了的。
但 Mermaid 也有局限:布局控制能力弱,复杂图容易乱。如果图特别复杂,比如超过 30 个节点,我建议用 Graphviz,它的布局算法更强。Graphviz 的语法稍微复杂一点,但值得学。
4.3 拖拽式工具的适用场景
拖拽式工具不是没有价值。在以下场景,我反而推荐拖拽式:
- 需要精细控制布局:比如给客户汇报的图,每个组件的位置都要精确到像素。
- 需要嵌入设计稿:比如产品经理要把流程图放进 PRD,用 Figma 更顺手。
- 非技术人员使用:比如运营同学画活动流程,Excalidraw 的手绘风格更友好。
我个人的工作流是:内部技术图用 Mermaid,对外汇报图用 draw.io 精调,头脑风暴用 Excalidraw。三者配合,覆盖所有场景。
5. 实战中的坑与经验:那些文档不会告诉你的事
5.1 图例不是越多越好
我早期做 diagram-design 时,特别喜欢加图例,觉得这样显得专业。后来发现,图例越多,读者越不看。因为读者默认图里的符号是通用的,一旦你自创符号,他们就得反复对照图例,理解成本反而上升。
正确的做法是:尽量使用行业通用符号。数据库用圆柱,用户用小人,队列用信封或六边形,这些都是约定俗成的。如果实在需要用自创符号,那就在图内直接标注,而不是放在角落的图例里。比如你在一个特殊组件旁边直接写“外部系统”,比在图例里写“虚线框=外部系统”更直观。
5.2 版本管理:图也会过期
这是一个容易被忽视的问题:图是会过期的。系统改了,图没改,下次有人照着图去理解系统,就会被误导。我见过最夸张的情况是,一张架构图还是三年前的版本,里面一半的服务已经下线了。
解决办法有两个:一是把图纳入版本管理,和代码一起提交;二是定期审查,比如每个季度检查一次所有架构图,过期的直接删除或更新。我倾向于第一种,因为代码驱动工具天然支持版本管理。每次改系统,顺手改图,提交时一起 commit,这样图和代码永远同步。
5.3 评审图而不是评审代码
这是一个反直觉的经验:在架构评审会上,先评审图,再评审代码。因为图比代码更容易发现结构问题。代码里一个循环依赖可能藏在几千行里,但图上一条反向箭头就暴露了。
我现在的习惯是:任何架构变更,先画图,图评审通过了再写代码。这样能避免很多返工。而且图评审的门槛低,产品、测试、运维都能参与,能提前发现跨角色的理解偏差。
5.4 不要追求一张图讲完所有事
新手常犯的错误是:试图用一张图表达所有信息。结果图变得极其复杂,谁也看不懂。正确的做法是分层:一张高层图讲系统边界和主要组件,若干张细节图讲内部实现。高层图给所有人看,细节图给相关开发看。
我通常会把图分成三层:L0 是系统上下文图,讲系统与外部的关系;L1 是容器图,讲系统内部的主要服务;L2 是组件图,讲单个服务内部的模块。每层图只讲一层的信息,不混在一起。这样每张图都清晰,而且读者可以根据需要选择看哪层。
6. 把 diagram-design 变成团队习惯
6.1 建立图库而不是散图
一个团队如果每个人把图存在自己电脑里,那图就失去了协作价值。正确的做法是建立统一的图库,所有图集中存放,按系统或项目分类。图库可以是 git 仓库,也可以是内部 wiki,关键是“统一入口”。
我建议图库的结构这样组织:
diagrams/ ├── system-a/ │ ├── L0-context.md │ ├── L1-container.md │ └── L2-component.md ├── system-b/ │ └── ... └── shared/ └── conventions.md其中conventions.md存放团队的 diagram-design 规范,包括形状词汇表、配色方案、连线规则。新人入职第一件事就是读这个文件,保证画出来的图风格一致。
6.2 把图纳入 Definition of Done
要让 diagram-design 真正落地,最有效的方法是把它纳入 Definition of Done。也就是说,一个功能完成的标志,不仅是代码写完、测试通过,还包括相关图更新完毕。这样图就不会滞后。
具体操作上,可以在代码仓库里放一个docs/diagrams目录,每次 PR 如果涉及架构变更,必须同时更新图。Code Review 时一并检查。刚开始可能会有阻力,但坚持两个月,大家就习惯了。
6.3 定期做图评审
除了架构评审,我建议每个季度做一次图评审。把所有图过一遍,检查三件事:一是图是否还准确,二是图是否符合规范,三是是否有可以合并或删除的图。这个评审不需要很长时间,一两个小时就能搞定,但能避免图库变成垃圾场。
我在实际使用中发现,图评审还有一个额外好处:它能暴露系统设计的问题。有时候看图才发现,某个服务的依赖关系已经变得很乱,但代码里看不出来。图是系统结构的“X光片”,定期拍一张,能提前发现病灶。
6.4 培养新人的图感
最后一点,diagram-design 的能力是可以培养的。我通常会让新人做一件事:拿一张现有的图,试着用文字描述图里的系统。如果描述不清楚,说明图有问题;如果描述清楚了,说明图合格。反过来,也可以让新人拿一段系统描述,试着画成图,然后对比现有图,看差异在哪里。
这个练习做几次,新人的图感就上来了。而且这个过程本身就在强化团队的 diagram-design 规范,一举两得。
我个人在实际操作中的体会是,diagram-design 最难的不是工具,而是“克制”。克制住加装饰的冲动,克制住堆信息的冲动,克制住自创符号的冲动。一张好图,应该是读者看完之后觉得“理所当然”,而不是“设计得真漂亮”。理所当然,才是 diagram-design 的最高评价。