1. 评审会上翻车之后:图表设计真正要解决的是"一眼看懂"
今年年初的一次架构评审,我拿着一张自己画了两小时的系统部署图上台。图里画了十几个服务节点、五六条消息队列、三条虚线表示的异步链路,还贴心地给每个服务框加了内部依赖的小字。讲完前两页,技术总监打断我:"你直接说,这张图想让我先看哪里?"我愣住了。那一瞬间我意识到,我画的不是图,是一张"信息堆放区"。
后来我把这个教训总结成一句话:diagram-design 的核心不是"把东西画出来",而是"让看的人用最短的时间找到他需要的信息"。很多人(包括当时的我)画图时会不自觉地站在"表达者视角"——我懂这个系统,所以我觉得每个细节都很重要。但看图的人往往是带着问题来的:这个流程哪里会失败?新服务部署在哪个网段?订单状态机有哪些合法迁移?如果图不能快速回答这些问题,那它和一段没人读的文档没有区别。
真正让我转变的是一次小小的实验。我把同样一个订单超时关单流程,分别用"把所有异常处理画在一张图里"和"只画主流程 + 单独一页异常分支"两种方式给两位新同事看,问他们"30 秒后描述这个流程"。前一位同事只说出"好像有很多判断",后一位同事直接说出了"超时之后先发消息再关单,关单失败会有补偿"。同一个系统,两种图,信息传递效率完全不同。从那时候起,我开始把 diagram-design 当作一门需要刻意练习的技艺,而不是一个随手就能完成的操作。
这篇内容不是软件操作教程,也不是某个具体工具的说明书。我想分享的是一整套我自己磨合了两年、在真实项目里反复验证过的图表设计工作流:从工具选型、各类高频图表的画法拆解,到颜色命名规范、交付前的检查项。适合所有需要画图表达想法的人——后端工程师、前端工程师、产品经理、架构师、技术作者,甚至做汇报材料时总被领导说"看不清重点"的职场人。如果你也经历过"画图两小时,讲解十分钟,提问没人懂"的尴尬,这篇文章应该能帮到你。
2. 先选型再动手:图表工具与表达方式怎么匹配
2.1 主流工具的定位差异:不是谁更强,是谁更匹配
很多人在工具选择上容易走极端:要么一直在用最熟悉的那一个,不管场景合不合适;要么每隔半年换一次新工具,导致团队协作成本居高不下。我用过的工具不算少,这里先给一个基于我自身经验的选型参考:
| 工具 | 最佳使用场景 | 上手成本 | 协作方式 | 我踩过的坑 |
|---|---|---|---|---|
| Excalidraw | 快速画草图、接口梳理、头脑风暴 | 极低 | 在线实时协作 | 手写字体风格偏随意,复杂架构图会显得不够严谨 |
| diagrams.net(draw.io) | 技术架构图、网络拓扑、UML | 低 | 本地文件 + Git 管理 | 默认形状库很乱,需要花时间自定义模板 |
| Figma | 产品原型图、用户流程图、UI 组件类图 | 中等 | 在线协作最强 | 画逻辑图时容易忍不住去抠像素,浪费时间 |
| PlantUML | 代码生成的 UML、时序图 | 低(写文本) | 适合文档嵌入 | 复杂的布局控制很痛苦,样式定制有局限 |
| Mermaid | Markdown 内嵌的流程图、时序图、状态图 | 极低 | 天然适合代码库 | 复杂分支会散成一团,布局不可控 |
| OmniGraffle | macOS 上高保真架构图、复杂版式 | 中等 | 本地为主 | 贵,而且 Windows 同事打不开源文件 |
不过这上面只是"偏向",不是"规定"。我自己目前的主力组合是:快速讨论用 Excalidraw,入库文档用 Mermaid 或 PlantUML,架构方案评审用 draw.io,涉及产品交互用 Figma。每个工具我都给它安排了一个明确的角色,这样在选择时就不用纠结了。
2.2 按场景选工具的底层逻辑:维护成本决定一切
选工具的时候,很多人的第一直觉是"哪个画出来更好看",但实际项目里更应该问的是:这张图的生命周期有多长?如果它是一次性讨论用的,两分钟后就要扔掉,那用 Excalidraw 快速涂改完全没问题。可如果它是系统设计文档的一部分,要在接下来一两年里持续被维护,那么"能不能方便地更新、能不能被 diff、能不能让新同事快速改"就成了决定性因素。
举例来说,我们有一个内部服务治理项目的架构图,最初是用白板工具画的,画完很漂亮,但三个月后服务从 12 个变成了 19 个,还拆分出了两个新网关,那张图就没人敢动了——因为原图作者离职,其他人不知道怎么在复杂画布里找到对应模块。后来我们把架构图迁到了 draw.io,并且用 Git 管理源文件,每次变更都走 MR(Merge Request)评审,图里的每个变更都和代码变更绑定在一起。这个迁移动作看似只是换了个工具,实际上是把图从"一次性展品"变成了"活文档"。
我的建议是:先问"这张图要被改几次",再选工具。要改很多次的图,优先选文本化、可版本化的方案(Mermaid、PlantUML、draw.io 源文件);只是为了让讨论更清晰的图,用画起来最快的方案就行,没必要在工具上消耗心力。
2.3 建立属于自己的组件库:工具之外效率翻倍的关键
不管用哪个工具,我都很建议花两个下午时间,按自己团队的业务特点搭一套组件库。什么意思呢?比如我的团队经常画订单相关的流程,我会在 draw.io 里固定一组形状:黄色的"系统外部依赖"框、蓝色的"内部服务"框、绿色的"数据库/存储"框、橙色的"人工操作"框。下次画图时直接从自己的图库里拖,不需要每次重新选颜色、调字号。
在 Excalidraw 里也一样。这个工具默认的图形虽然少,但支持把常用组合保存为"库"。我把"消息队列""定时任务""外部 API 网关""缓存"这些常见的元素都做成了库文件,画图速度至少快了三分之一。很多画图慢的人,慢的不是思考,而是在反复调整同一个形状的格式上。组建一次组件库,后面所有图都受益。
3. 四类高频图表的实战拆解:从画框到讲清逻辑
3.1 业务流程图:先写步骤清单,再画分支
业务流程是大家画得最多也画得最容易乱的图。最常见的坑是:一张图画了主流程、异常流程、补偿流程、定时任务兜底流程,看起来"非常全面",实际上阅读者根本分不清哪条线是主干。
我现在画流程图的顺序和大多数人不太一样,我先在文字里把步骤一条条写出来,全部确认之后才开画。比如画一个"用户申请退款"的流程,我会先列:
- 用户提交退款申请
- 系统校验订单状态(是否已完成、是否已超过退款时限)
- 如果校验失败,返回原因并结束
- 如果校验通过,调支付网关发起原路退款
- 支付网关返回成功 / 失败
- 成功则更新订单状态为"已退款",失败则进入人工审核队列
文字确认后,画图就只剩排版了。这样做还有一个额外的好处:先写文字清单时,很容易发现自己漏了某个分支。比如退款失败之后需不需要通知用户?人工审核结果怎么回到主流程?这些在文字阶段就暴露出来的问题,比画到一半再改要省力得多。
画的时候我还会遵守一条"三色原则":正常路径用一种颜色,异常分支用一种颜色,定时/异步补偿用一种颜色。并且默认把主流程画成自上而下的直线,异常分支放在右侧。这样读者第一眼看到的是那条垂直主线,不会被旁路带偏。
3.2 系统架构图:分层思维与边界表达
系统架构图是 diagram-design 里最容易被"画得像拓扑图"的类型。很多人把服务名往画布上一摆,线上连上线,就宣布"这是架构图"。但一张合格的架构图,核心是三个问题:系统分几层?每一层的边界在哪?层与层之间怎么通信?
我的画法是"水平分层 + 垂直泳道"的混合结构。水平方向把基础设施层、应用层、网关层、客户端层从上到下或从下到上展开,每一层用一个大的背景色块包起来。垂直方向则用泳道区分不同业务域(比如订单域、支付域、用户域),这样既能看出整体层次,也能看出每个业务域内有哪些服务。
关于边界的表达,我特别想提醒一点:能用"层"表达关系,就不要用"线"表达关系。两个服务之间的具体依赖是容易过时的信息,今天 A 调 B,下周可能就加了一个 C。如果每一条调用关系都要画成线,图会越改越密,最后变成一团意大利面。更稳妥的方式是:在分层图中只表达"这一层允许调用下一层"的规则,具体到服务间的调用细节,用一张独立的时序图去表达。
3.3 时序图:谁和谁在什么时刻说了什么
时序图是我觉得最"反直觉"的一种图。它的核心元素是纵向的时间轴,但大多数新手画时序图时想的是"系统怎么工作",而不是"对象之间按什么顺序发了什么消息"。
画时序图之前,我会先确定三件事:参与者有哪几个?每条消息的触发条件是什么?每条消息是同步还是异步?参与者不是类的数量,而是能独立收发消息的角色。比如一个"创建订单"的时序图,参与者至少是:客户端、订单服务、库存服务、支付服务、消息队列。如果把"订单服务内部的数据库操作"也当成一个参与者,图会迅速变得臃肿。
有一个我经常提醒自己的小技巧:消息的命名要像软件工程里的方法名一样规范,动词开头,说清楚在干什么。比如"创建订单请求"和"POST /api/orders"这两种写法里,我倾向于后者,因为它更精确——前者既不知道是接口还是内部方法,也不知道是同步还是异步。给消息命名时稍微多想一下,看图的人就能少猜很多。
异步消息的表示也值得注意。很多人用虚线箭头画所有异步调用,但没有标明回调或消息队列的 topic。我建议在虚线箭头上直接标注队列名或事件名,例如"emit: OrderCreatedEvent",这样阅读者不需要再翻代码就能知道消息走的是什么通道。
3.4 ER 图 / 领域模型图:字段不是重点,关系才是
画 ER 图(实体关系图)和领域模型图时,最容易犯的错是"把表结构直接平移画出来"。一个订单表有 30 个字段,画图时全列出来,读者盯着字段列表,反而看不出订单和用户、订单和商品之间的关系。
我的做法是:实体框里只保留三个要素——实体名、关键标识、与当前讨论强相关的 2~3 个字段。剩下的字段,要么省去,要么放在附录。图的价值是呈现"关系",不是呈现"表结构"。
关系线是 ER 图真正的主角。我会用**韦氏线(crow's foot notation)**表示一对多、多对多,而不是简单地画一条线然后在旁边写一小段文字。人眼对图形的感知速度远快于文字,如果一对多关系还要靠读注释才能理解,那这张图就不够好。另外,关系的动词最好也标在线上,如"提交""包含""属于",这会让图的语义清楚很多,尤其是多个实体关系相似的时候。
4. 把设计规范固定下来:颜色、布局、命名与版式
4.1 颜色语义化:让颜色替文字说话
在图表设计里,颜色最大的价值是形成条件反射。看到蓝色就知道是内部服务,看到红色就知道是异常/告警路径,看到灰色就知道是暂时不展开的辅助信息。一旦建立起这种约定,看图的人就不用每次去读框里的文字了。
但颜色用不好也会帮倒忙。常见的错误有几种:一是颜色种类太多,一张图超过 6 种颜色,读者会开始怀疑"这个颜色是不是有特殊含义",注意力会被分散;二是部分颜色相近,比如深蓝和深绿,在投影仪上几乎无法区分;三是只依赖颜色传达信息,不考虑色盲读者。
我现在的规范是:主色不超过 4 种 + 中性色(灰白黑)不限。主色分别对应核心服务、外部依赖、数据存储、人工流程。色盲友好的角度,我会避免红绿搭配,而是用红蓝搭配,并在重要节点同时加形状或线型作为第二通道。比如异常路径不仅用红色,还配上"X"形标记或者虚线边框。
4.2 三分构图与视觉动线:引导读者按你的顺序看
画布不是无限大的白纸,它有边界、有视觉重心、有阅读顺序。很多图之所以"看不出重点",不是因为信息不够,而是排版没有动线,读者的视线像无头苍蝇一样四处跳跃。
我的排版手法借鉴了平面设计里的三分法:把画布想象成九宫格,重要内容放在左上和中上区域,次要内容放在右侧和底部。中文阅读习惯是从左到右、从上到下,所以主流程的起点应该放在左上角,然后顺着一个大致的方向铺开,而不是画成从正中间开始向四面发散的结构。
另外,每一张图都应该有且只有一个"视觉锚点",就是那个最核心的节点或流程。这个锚点要么在左上角,要么在正中央,并且尺寸可以比其他节点略大一圈。其他节点再重要,也不能抢它的视觉权重。做到这一点之后,图会立刻显得"有主次"。
4.3 命名与编号体系:一张图就是一份索引
当图表数量多起来之后,布局、颜色和经验会影响看图效率的瓶颈反而会变成命名。如果你的团队所有图都叫"架构图""流程图"或"未命名文件",那维护和引用就是一场灾难。
我会坚持一套简单的命名规范:"前缀-模块/业务域-图类型-版本"。例如:"ARCH-订单中心-部署架构-v2"、"FLOW-退款异常-活动图-v1"。图片内涉及可被引用的节点(比如服务、接口、数据表),则使用统一的编号,例如"订单服务(SVC-ORD-001)""订单表(TBL-ORD-001)"。有了编号之后,不论是文档引用还是口头沟通,都只需要说编号,不需要含糊地"就是那个,右边中间的框"。
这套命名体系一开始有点麻烦,但项目规模变大之后,收益非常明显。因为图已经变成了团队沟通的索引,而不再是一个孤立的展示品。
5. 实测中反复踩过的坑:交付前的检查项清单
5.1 信息重叠与跨层连线:图越大越难维护的根因
画图时有一个非常普遍的心理:总觉得"这张图少画了点什么",于是不断往里面加信息。加到最后,图变大了,信息完整了,但也不再有人愿意看了。这就是我为期半年最深刻的教训:一张图的有效信息量是有限的,超过了阈值,阅读者就会放弃理解。
我现在的原则是"一图一主题"。如果一张图需要表达的内容超过 7 个核心节点或 5 个主要分支,我就会认真考虑把它拆成多张图。拆分的维度可以是:按流程阶段拆(前端流程 / 后端流程 / 异常补偿)、按抽象层次拆(整体架构 / 模块细节 / 关键时序)、按角色拆(买家视角 / 卖家视角 / 运营视角)。
跨层连线的处理也一样。画架构图时,最忌讳的是"为了表达某个特殊情况",直接从最底层拉一条线连到最顶层。这会让读者觉得系统没有边界,到处都有隐式依赖。正确的做法是:如果确实存在跨层调用,单独画一张小图来说明这个特例,而不是在总图上拉一条破坏整体视觉的长线。
5.2 文件的版本管理:图源文件比导出图更重要
很多人交付图表时只给一张 PNG,却把源文件留在自己电脑里。一旦图需要更新,其他人只能"照着图片重新画一张",这本质上是在浪费整个团队的时间。
我们现在所有进入正式文档的图,都必须同时提交源文件和导出文件。源文件放在 Git 仓库里,和代码一起走评审。Mermaid 和 PlantUML 这类文本化工具天然支持 diff,用 Git 管理起来非常舒服;draw.io 和 Figma 这类可视化工具则通过.drawio.xml或法律依赖文件(.fig)保存,Git 也能版本化,只是 diff 可读性稍差一些。
你可能觉得这只是团队流程问题,和图表设计本身没关系。但我的亲身体会正相反:版本管理直接决定了你会用多大心力去保证图的质量。如果你的图源文件永远不会被第二次打开,那你肯定不会花心思去把它画得易维护;只有当你知道这张图会持续被 review、被修改,你才会主动去优化布局、命名和层次。工具和流程会反向塑造人的习惯,这是一件很奇妙的事。
5.3 交付前必查的 7 个问题:每次发布前过一遍
在把图发给别人或贴进文档之前,我会强制自己过一遍下面这份检查清单。它不复杂,但每次都能拦下至少一个问题:
- 这张图的主题是什么?如果只能说"这是 XX 系统架构图"而说不出一句"我想让读者重点注意什么",那这张图大概率还需要拆或改。
- 主流程/主结构是否在视觉上是第一眼注意到的?让一个第一次看图的人花 5 秒描述他看到了什么,如果他的描述和你想要传达的重点不一致,就是排版有问题。
- 有没有纯装饰性的内容?有些渐变、阴影、剪贴画元素,除了好看没有任何信息价值,反而会增加视觉噪音。
- 文字能不能被清晰识别?字体小于 12px 的文本,在不同分辨率屏幕或打印出来后基本不可读。放大图片后所有文字仍然清晰,这是底线。
- 同一个含义是否只用同一种表达?比如蓝色框一会儿代表服务,一会儿又代表外部系统,读者一定会混乱。全局统一术语和颜色语义。
- 跨引用是否一致?图里提到的服务名、接口名、队列名,和代码里是否一致?如果不一致,读者会直接对着图踩坑。
- 是否有边界说明?这张图画到哪个范围为止?不含哪些内容?给图加一个简短的说明文字或图例,能避免很多"这图怎么缺了 XX"的质疑。
这条检查清单现在已经成为我们团队评审设计文档时的标准流程。如果你觉得每次画完图自查太麻烦,也可以降低频率,只在进入正式评审或对外发布前过一遍。但相信我,检查出来的问题,远比花掉的五分钟值钱。
我自己现在画图的心态,已经从"赶紧把脑子里的想法倒出来"变成了"让读到这张图的人真正省时间"。这个转变花了我将近两年的时间,中间画废过几十张图,踩过无数个上面提到的坑。如果你刚开始认真对待 diagram-design,不用急着追求一步到位。先把工具选顺手,把主色和命名规范定下来,再按清单过几轮,你的图就会开始变得不一样。