做架构设计、技术方案评审、业务汇报这么多年,我越来越觉得画图这件事本身就是一种设计能力,而且是被严重低估的能力。diagram-design这个词看起来像是一个工具包的命名,但落到实际工作里,它代表的是"用图表达复杂关系"的完整方法论:从信息层级划分、布局规划、视觉语言统一,到版本管理、团队协作、自动化生成,每一步都有讲究。
我能做、也一直在做的,就是用图表即代码的方式,把架构图、流程图、时序图从"一次性画完就过时"的静态图片,变成"跟着代码和文档一起迭代"的动态资产。这篇文章就围绕我沉淀下来的整套diagram-design实操经验展开,适合正在做系统设计、技术文档维护、架构治理的同学参考。不管你是第一次接触还是已经用了一段时间,这里面有不少细节是我踩过坑之后才补上的,值得看完。
1. 为什么我把图表设计从绘图搬进了代码
1.1 传统绘图软件搞不定的事情
早些年我做技术方案,用的还是带图形界面的绘图工具。拖拽图形、画箭头、对齐、填颜色,一张图折腾半小时起步,等架构调整的时候,回去改图又是一轮大工程。后来我统计过一次,那张系统架构图在一个季度的迭代里被改了七版,没有一版是完整同步到文档里的,因为大家默认"改图太费劲,先不改了,等定稿再说"。
这背后有个很容易被忽略的问题:传统绘图工具把"画图"和"设计"混在了一起。你在拖拽一个个矩形的时候,注意力其实集中在坐标对齐、颜色搭配这些表面操作上,而真正重要的信息结构、节点关系、数据流向,反而被弱化了。等到图越来越大,几百个节点叠在一起的时候,别说是维护,光是看清都费劲。
还有一个更实际的痛点是协作。一个团队里五个人,每个人打开同一份绘图文件,看到的是各自攒出来的草稿。你说这是最新版,我说我改了接口,最后合并的时候发现版本对不上,图里的内容和代码已经完全是两套东西了。
1.2 图表即代码的核心逻辑
后来我切换到图表即代码的工作方式,核心就一句话:用纯文本描述图表结构,用工具自动渲染成图。你写一段结构化的文本,声明"系统A调用系统B,B依赖数据库C",渲染引擎就帮你画出对应的框和连线。
这个切换带来了三个本质变化。
第一,图表变成了可追踪的文本资产。只要文本进了版本控制,每一次改动都有记录,是谁在什么时间改了哪个节点,回退、合并、评审都跟管理代码一样简单。我团队里现在评审架构图,直接在代码评审流程里看 diff,不用来回传文件。
第二,结构优先于样式。写文本的时候,你被迫先想清楚"有哪些东西、它们之间什么关系",而不是一上来就纠结"这个框用什么颜色、放哪个位置"。等结构定了,样式交给样式模板统一处理,一致性天然比手工排版高一个量级。
第三,自动化成为可能。文本可以嵌入文档、嵌入代码仓库、嵌入自动化流水线。每次代码变更触发重新生成架构图,图永远跟着代码走。
我在实际项目中把diagram-design落成了一根流水线:设计文档里维护图的源文件,提交到仓库之后由构建任务自动渲染出 SVG 和 PNG,发布到内部知识库。整个过程不需要人工去"画"图,要改的时候改文本、重新提交、重新渲染。这套流水线跑了两年多,最大的体会是:当图不再依赖某个人手工维护的时候,大家才真正愿意把图画完、画准。
2. 图表设计的第一原则:先定信息层级,再动手画图
2.1 架构图的空间布局逻辑
我见过太多失败的架构图,问题往往不是关系画错了,而是所有元素在视觉上都是同一个层级。十几二十个服务框,大小差不多、颜色差不多、位置随缘,看起来像一碗大杂烩。
真正的diagram-design应该从信息层级开始。拿到需求之后,第一件事不是找工具,而是把要表达的内容分成三层:
- 全局层:这个图整体的边界是什么,涉及哪些子系统或领域。
- 核心层:当前要重点表达的逻辑,通常是主链路、核心依赖。
- 支撑层:外围的配置、监控、数据管道等辅助组件,不能抢主链路的戏。
层级清晰之后,布局才有依据。我的习惯是:主链路从左到右展开,支撑组件放在主链路下方或两侧,跨领域边界用分组容器表达。左侧放入口或触发方,中间放核心处理节点,右侧放最终的数据落点或消费方。用户的请求从左边进来,经过中间几个核心服务,最终落到右边的存储,这条主线一眼就能读出来,不会绕。
这里有个细节:主链路节点之间的间距要均匀,均匀会让视觉上产生"这条路是连续的"暗示。如果节点 A 和 B 之间距离很大、B 和 C 之间又挤在一起,读者会下意识以为它们之间有什么特殊关系。距离也是一种信息,不要让无意的距离制造误解。
2.2 元素分级与视觉权重分配
层级在逻辑上定好了,接下来是视觉权重分配。设计上有个基本概念叫视觉重量,面积大的、颜色深的、边框粗的元素会先被看到。在设计图表时,这个规律要主动利用,而不是被动接受。
我的做法是给节点定义四种视觉等级:
- 一级节点:核心服务或关键系统。视觉上面积略大,使用主色调,边框清晰。
- 二级节点:主要依赖或上下游系统。面积正常,使用中性色。
- 三级节点:辅助组件或数据存储。面积紧凑,弱化色彩。
- 分组容器:表达逻辑边界和层级归属,用区块背景或虚线边框。
实际操作中,我用一套统一的样式模板来控制这些权重。比如一级节点填充色最深、二级次之、三级接近浅灰;所有节点统一用同一种圆角半径和字体大小,避免一个图里出现三种风格完全不同的框。
很多人维护图表时为了"好看"会不断加颜色,结果一张图成了彩虹。我的经验恰恰相反:颜色种类越少,图越高级、越容易读。架构图里颜色承担的职责应该是"表达层级归属"而不是"装饰"。不同颜色代表不同业务域,同一个业务域内统一用一种颜色,通过深浅区分层级,这样颜色就有了语义,而不是纯粹的视觉刺激。
3. 核心细节解析与实操要点
3.1 文字简洁与标签命名规范
图上每个节点的文字,是最容易被忽视却影响最大的设计要素。理想状态下,一个节点标签要能在三秒内被理解,超过三秒就说明命名有问题。
根据我长期维护图表文本的经验,命名有几个可复用的原则。
原则一:动词开头表达行为,名词开头表达实体。比如"调用订单服务"比"订单服务调用关系"清晰得多,"订单服务" 比 "该服务用于处理用户下单相关业务逻辑" 好理解。
原则二:同一张图内,命名维度必须一致。如果你把一部分节点命名成"XX服务",另一部分命名成"XX系统",甚至有的写"XX模块",读者就会困惑它们之间是层级关系、从属关系还是并列关系。我通常全部统一为"系统"或"服务"维度,为了更明确,加上角色,比如"订单服务(提供方)"。
原则三:标签长度控制在三到七个字左右,最长不超过十个字。超过之后,要么是逻辑拆得不够细,要么是命名过于啰嗦。如果信息确实多,拆成标题加备注的形式,标题保持短,备注放在节点内作为辅助说明。
另外我强烈建议在团队内部定一份命名词典,把常用系统、服务、数据库的统一命名固定下来。这看起来是个文案工作,实际却能省掉大量沟通成本。没有统一命名的时候,同一个系统在这张图叫"用户中心",那张图叫"会员服务",开会讨论的时候经常要为"是不是同一个东西"扯半天。
3.2 连线与箭头语义统一
连线是图的骨架,箭头则是语义的载体。很多人画图的时候对箭头很随意,但这恰恰是整张图里信息密度最高的部分。
我建议团队明确四种基础箭头语义:
- 实线箭头:同步调用或数据请求,最常用的关系。
- 虚线箭头:异步通知或事件订阅,强调时间解耦。
- 实线无箭头:物理连接或配置关系,不强调方向。
- 双箭头或多标签:单向数据流与回执,在需要表达完整交互时使用。
关键点在于:一种箭头只表达一种语义,全程一致。如果你在这张图里用实线箭头表示同步调用,就不要再拿它表达数据迁移,那会让图形语言彻底失效。
连线本身也有讲究。主链路的线要比分支连线略粗,颜色更实;分支连线保持统一的浅色调。不要让连线互相交叉得过于复杂,交叉是没办法完全避免的,但可以通过调整节点位置、翻转链路方向来减少。一个很实用的技巧是:让主链路保持水平,把分支都放到同一侧,用垂直方向展开,这样交叉概率会小很多。
连线上的文字标签同样要克制。能用连线方向和颜色表达的信息,就不要用文字再写一遍。真有必要写,保持短语级别,比如"定时同步""事件回调"就够,不要写一整句话放在线上,渲染出来又密又乱。
3.3 颜色与样式管理的边界
我见过团队在样式上纠结太久的场景,几个人为了"这个框是蓝色还是青色"争论不休。这其实是目标错位,颜色的价值是辅助理解,而不是成为争论点。
与其在每次画图时手动指定颜色,不如通过样式统一模板解决。我维护了一份全局样式配置,里面定义了几套预设样式:主系统、依赖系统、存储、消息队列、外部边界、分组容器等。任何新图都从这些预设样式出发,业务上特殊的用额外标记,而不是通过新增颜色来处理。
这样做的直接效果是:不同人画出来的图放一起,视觉语言是一致的,看的人不需要重新学习每张图的颜色含义。
另外,连方向和颜色都表达不了的关系,再考虑用标注。比如"这一步有重试机制"或者"这条链路未来会改成异步",用注释放在图例里,不要在图上乱画。图例是必须的,尤其当颜色承载语义之后,没有图例的彩色图等于自嗨。我每张正式交付的图都会附一个简短图例,交代箭头语义和颜色归属。可能有人觉得图例多余,但当一张图被第三个人看的时候,图例就是唯一的解释通道。
4. 实操过程:从需求到一张合格的系统架构图
4.1 需求收集与元素清单
动手写文本之前,我会先做一步很多同学会跳过的动作:列元素清单。
拿着需求,先把图里必须出现的系统、服务、数据存储、消息通道、外部依赖全部列成清单。每个元素后面标注它的层级归属、与主链路的关系,以及是否有文字备注要写。这一份清单相当于图的"内容底稿"。
举个例子,我之前帮一个订单处理系统画架构图。需求描述是"用户在前台下单,系统核验库存,同时发送消息给财务系统,之后订单入库"。我列的清单就是:
- 用户端(入口,一级节点)
- 订单网关(核心节点,接收下单请求)
- 库存服务(核心节点,核验库存)
- 订单库(数据存储,订单数据落库)
- 消息队列(支撑组件,订单创建后发送事件)
- 财务系统(下游系统,接收订单事件,处理入账)
清单列完之后,再看这些元素之间的关系,把它们标注成"调用、数据流、消息、依赖"中的一种。这一步做完,图的文本框架基本就出来了。
4.2 绘图环境配置与工具选型
diagram-design的落地,离不开工具链的选型。我的标准是:优先选择支持纯文本渲染、能接入版本控制、渲染质量可控的开源方案。这样团队没有额外商业软件依赖,构建流程也更透明。
在我习惯的工作流里,环境配置包含三块:
第一块是渲染引擎。我用的方案,既能处理流程图、时序图,又能输出 SVG 和 PNG,语法简单,学习成本低,适合团队推广。不一定追求最复杂的绘图能力,关键是团队里每个人都能快速上手,样式的一致性靠预设模板保证。
第二块是实时预览工具。写过图表文本之后,本地起一个监听模式,文件一保存浏览器自动刷新,所见即所得。这一步非常提升写图效率,不用反复走"提交、渲染、查看"的完整循环。
第三块是样式配置。把前面提到的颜色、箭头、字体、间距全部集中到配置里,渲染时自动带上。这样团队成员写图的时候不需要关注样式,专注把结构写对就好。
我推荐新手一开始不要追求工具大而全,先用一套最小的方案跑通闭环:一个渲染引擎、一个实时预览、一份样式配置,足够覆盖日常 90% 的需求。
4.3 完整绘图流程与代码实现
这里我以一个常见的"下单核心链路"图为例,展示我实际用来生产架构图的方法。
先定义分组。我会用文本语法声明两个组:核心业务域和外部依赖域。核心业务域里放用户端、订单网关、库存服务、订单库;外部依赖域里放消息队列、财务系统。
接着定义节点和关系。每个节点用标识符加上标签和样式标注;关系用一行声明,表达从哪个节点到哪个节点的什么语义。
文本内容大概是这个风格:
组:核心业务域 节点:用户端 节点:订单网关 节点:库存服务 节点:订单库 组:外部依赖域 节点:消息队列 节点:财务系统 关系: 用户端 -> 订单网关 :提交订单 订单网关 -> 库存服务 :核验库存 订单网关 -> 订单库 :落库 订单网关 -> 消息队列 :发布订单事件 消息队列 -> 财务系统 :异步通知这个文本有三个好处:结构一目了然;关系声明和代码很像,团队能直接做评审;渲染出来之后,布局由引擎自动排列,不需要人肉拖拽。
写完之后,我会检查一次"图上每个节点是否都在文本里有存在感"。有些团队画的图看似完整,仔细看有个服务在图上出现了,但在文本里没有任何出边或入边,成了孤岛节点。这种情况要么是逻辑遗漏,要么是文本没写完整,本质上都是图有问题。
4.4 输出与交付
图渲染出来之后,还差最后一步:输出与交付。
我的交付标准是不止一张图片。图片是给人看的,但你还需要给图配套一份简短的说明,交代三件事:这个图表达的范围是什么,它的适用场景是什么,如果后续要改动该改哪里。这三点写成一段话附在图下面,直接放进文档。
输出格式上,我会同时生成 SVG 和 PNG 两个版本。SVG 用于知识库里保留矢量清晰度,PNG 用于插入离线文档或做外部分享。如果文档系统支持直接引用 SVG 源文件,我一般优先用 SVG,方便任何人在浏览器缩放而不失真。
交付前,我还会做一遍"看图不看文字"的自测:把图留给没参与设计的同事,让他只看图复述一遍业务流程。如果他能复述出主链路和关键关系,这张图就是合格的;如果他卡在某处反复琢磨,那这个地方一定有问题,回炉重写文本。
5. 常见问题与排查技巧实录
5.1 图表元素过多,挤成一团
这是我最常被问的问题:"我系统比较大,节点多,怎么画都不会清晰,怎么办?"
先说结论:当一张图里节点超过二十个,就不应该再试图做成一张图了。这不是绘图技巧的问题,而是信息架构的问题。
我的处理办法是分层出图。把系统拆成三张图:
- 总体架构图:只放核心服务、外部依赖和主链路,控制在十个节点以内。
- 分域详图:按业务域拆,每个域内部把细节画清楚。
- 部署视图:体现物理部署、容器分布和网络区域。
三张图互相引用,文档里给出跳转关系。读者先看总体图建立认知框架,再按需进入分域详图。这样每张图的信息密度都适中,既讲得清又读得懂。
如果你确实不想拆,也有一个缓解技巧:对节点做聚合。把相关联的小服务聚合成一个组件,图上只画聚合后的组件,细节放到组件内部的说明里。聚合的关键是找到合理的边界,比如按部署单元、按团队归属、按业务功能都能作为聚合依据。聚合之后图面立刻清爽很多,但代价是细节被隐藏,需要靠文档补充。
5.2 版本迭代后图与文档脱节
很多团队面临的真实问题是:图刚画完是准的,过俩月代码迭代了几轮,图就过时了。图的维护速度永远赶不上代码变化速度。
解决这个问题,我试过的办法里有三个比较有效。
第一个是前面提到的:把图源文件放进版本仓库,和代码一起提交。代码改造涉及架构调整时,同一个合并请求里带上图的变化,评审人能看到图和代码是同步改的。这样图就不是"事后补文档",而是"跟着改动一起走"。
第二个是建立定期巡检机制。每过一个迭代周期,跑一次对照检查:把图上声明的服务和线上实际运行的服务列表对齐,找出图上在跑但代码已删除的节点、代码里新增但图上没体现的节点,形成差异清单,列入下期技术债。机制本身不难,难的是坚持,但一旦坚持下来,图的可信度会显著提升。
第三个是一开始就别画"过于详细"的图。图表达稳定结构,细节交给文字说明。因为稳定结构变化频率低,过时速度慢;而高频变化的细节如果放进图里,要么图不断被更新打扰,要么很快失真。把容易变的部分用文字描述放在图下方,反而能延长图的保质期。
5.3 团队协作中的样式混乱
这个问题主要出现在多人维护同一批图的时候。每个人有自己习惯的配色、间距、标签风格,结果就是同一套系统,在不同文档里的图长得完全不一样,读者每次都要重新适应。
我在团队里用的方式比较直接:定一份样式规范文档,内容包括预设样式清单、箭头语义表、命名规则、交付格式。任何人都必须先读这份规范再画图。规范不追求大而全,只解决高频问题。
但光有规范不够,样式要落到配置里。我通过全局样式模板让渲染默认生效,团队写图的时候根本不需要手动选颜色,看到的成品天然一致。如果有特殊需求必须额外定制,他需要在一句话备注里给出理由,同时这个定制会进入评审视野,防止样式在新图里悄悄蔓延。
规范加上默认模板,双管齐下之后,我团队的图从之前那种"一眼看出谁画的"迅速收敛成"体系内统一风格"。后来再有外部同学看我们文档,反馈是"你们的图有辨识度",这说明视觉语言已经沉淀成团队资产了。
6. 让图表发挥更大价值的额外实践
6.1 架构图与代码结构映射
架构图如果只是给人看的文档,它和工程的联系还是脆弱的。我后来做了一件事:把图里的关键节点和代码仓库里的模块路径映射起来。这远比想象中有效。
比如图上有一个"订单网关"节点,我就在节点说明里标注它对应的代码模块、核心接口名,甚至在 metadata 里写入具体的代码路径。这样读者看图的时候能直接跳到代码,排查问题不需要从图到文档再到代码绕一大圈。
更进一步,可以通过脚本扫描代码里的接口定义,自动生成或校验图里声明的依赖关系是否属实。比如图上画了"订单网关依赖库存服务",脚本检查到订单网关的代码里确实存在对库存服务接口的调用,那么这条边就被"验证通过";如果代码里根本没有对应调用,图就需要修正。这个实践听上去复杂,做起来其实是个小脚本的活儿,但它把图的真实性从"人保证"提升到了"构建任务保证"。
6.2 图表设计的过程管理
图纸作为交付物,管理的不只是最后那张图,还有设计过程。我习惯保存不同阶段的版本,评审时对照展示这个图经历过哪些取舍。
一次架构调整的图,至少要经历三版:
草稿版,把所有候选元素和关系铺进来,先确保没漏项,哪怕布局乱、命名糙。
结构化版,分组、分层、约束命名、连线条数精简。这版解决"读不读得懂"的问题。
交付版,接入样式规范、补充图例和说明文字,输出正式文档。这版解决"看不看得清、可不可用"的问题。
这三个版本我全都会提交到仓库保留,评审不只看最终结果,还能追溯决策过程。有人质疑某一版的时候,可以指出前两版里做过什么尝试、为什么放弃。图纸设计其实和技术方案设计一样,过程同样值得被记录。
6.3 适度自动化,避免为了自动化而自动化
自动化是方向,但要设边界。我见过团队把很复杂的逻辑塞进自动渲染脚本,最后脚本成了新的维护负担。自动化要解决的是人的重复劳动和一致性,不是消灭所有手工操作。
我给自己定的自动化原则是:高频低频均匀处理,凡涉及一致性问题的靠模板,凡涉及真实性的靠验证,凡涉及内容判断的靠人工。图的业务内容和语义判断,比如"这个系统为什么要依赖另一个系统"、 "这条消息为什么是异步而不是同步",这些永远无法自动化,也不应该自动化。
自动化的正确姿势是:把"低价值、高重复、强调格式一致"的环节自动化,把"高价值、需要判断、强调内容准确"的环节留给设计者。拿捏好这个度,自动化才是帮手,而不是枷锁。
7. 写在最后的实操体会
做了这么多年diagram-design,我最想分享的一点体会是:图是给人读的,不是给自己写的。很多图画完之后,画图的人很满意,但换一个人来看,根本不知道该往哪里聚焦。信息层级不清、箭头语义混乱、颜色没意义,这类问题比"少画一个系统"更隐蔽也更有杀伤力。
我每次交付图表,都会强制自己站在一个陌生读者视角做一次"清水测试":不依赖任何口头解释,只靠图本身和一个图例,看看主链路能不能读通、关键依赖是否能定位。测试失败的图,无论当初构思多完美,都要回去改。
另外,图表的进化是持续的。别指望一天就能设计出完美架构图,也别第一次落模板就想覆盖所有场景。我在实际项目里是不断从新图中总结规律,把重复出现的结构调整成模板,把踩过的命名坑写进规范,逐步形成一套属于这个团队的图表设计语言。这个过程很慢,但值得。
如果你刚准备尝试这套工作方式,我建议从一张你最熟悉的系统架构图开始,把它用文本方式重构一遍,再配上统一的样式。你大概率会发现,从前绘图软件里那些让你头疼的对齐、配色、维护问题,在这个工作流里被结构性地化解了。剩下的,就是坚持把图当作代码一样维护,它回报你的,将是一套长期准确、可演进、能看懂的系统可视化资产。