1. 图看着挺专业,评审时却总被追问:问题出在哪
上周项目评审,同事把自己负责的模块架构图投上大屏。图做得很用心:配色统一、圆角一致、每个框都排得整整齐齐,连阴影都调得恰到好处。可第一位评审开口就问:"这两个框之间的箭头,是调用关系还是数据流?"紧接着第二问:"这两个框为什么并排放?是同一种部署单元吗?"第三问:"这块区域颜色更深,是表示更核心吗?"十分钟之后,解释图的时间已经超过了画图时间的十倍。最后结论倒是一致的:图很好看,但提供不了决策依据。
这不是个例。这些年我经手过不少架构图、流程图、时序图和部署图,慢慢摸出一个规律:大家画图都很认真,但真正能被一眼看懂的图,十张里不到两三张。问题通常不在审美,而在设计。diagram-design 这件事,本质不是"把图画好看",而是"让图在第一时间完成信息传递的使命"——用准确的节点、清晰的连线、无歧义的视觉编码,把作者脑子里的模型无损交付给读者。这篇内容适合经常画系统图、业务图、流程图的开发、运维、产品和测试同学,也适合带新人、做汇报时需要以图说事的任何角色。我会按自己的实战思路来拆:先讲画图前怎么把问题定义清楚,再讲三类高频图型的具体画法,然后是视觉表达细节、检查清单,最后聊工具和多人协作的坑。
1.1 一个典型的"图很好,但没人懂"现场
继续上面那位评审同事的例子。他画的是某跨平台系统的核心服务关系图,框有七八个,线有十几条,用了三种颜色和两种线型。问题在于:这些颜色和线型从来没有在图上或文档里被定义过。他觉得"绿色是正常路径、红色是异常路径、虚线是异步"是自己的常识,可对第一次看到这张图的人来说,这些符号全是需要猜测的密码。
更麻烦的是,他试图在一张图里塞进两层信息:一层是系统部署拓扑,哪个服务部署在哪台机器上;另一层是服务调用链,谁在什么时候调用谁。于是"线穿过框"的现象出现了:一条调用线从第一个服务的框出发,横穿第二个服务的框到达第三个服务,阅图者根本分不清这条线是"经过第二个服务"还是"跟第二个服务无关"。被问到的时候,作者自己也要想一会儿才能解释清楚。
这种现场我见得太多了,几乎可以总结成一种"图纸事故"的固定套路:节点含义不清、连线语义混乱、抽象层次混杂、颜色随手用、没有图例。任何一项单独出现都不致命,但凑在一起,一张图就成了只有作者能破译的私人密码本。
1.2 图的本质是信息压缩协议,不是艺术创作
为什么会出现这种情况?因为很多画图的人默认了一条错误前提:图是给自己看的,或者图只是"文档里该配的一张插图"。可实际上,图是一种信息压缩协议。作者把脑内一个高维复杂模型,压成二维平面上的点和线;读者需要面对这些点和线,把它解压回自己脑中。这个过程的成功率,取决于双方是否共享同一套约定。
拿文件压缩打比方:你用某种私有算法压缩了一个文件,解压时必须用同一种算法,换了软件就只能得到乱码。图也是这个道理。你自定义了颜色、线型、形状的含义,但没把这个"算法"告诉读者,读者拿到手就只能靠猜。评审会上一连串"这是什么意思"的提问,翻译过来就是:读者正在暴力破解你的私有协议。
所以我在推进 diagram-design 时,第一件事永远是建立并维护"约定":哪些形状代表节点类型、实线和虚线分别代表什么、颜色有没有语义、箭头指向代表什么。这个约定可以很轻,一两页纸就够了,只要团队里人人可见、人人遵守,图的质量立刻会有质的变化。细节我在后面工具协作那节再展开。
1.3 判断一张图好坏的三个层次
经历多了之后,我给自己定了一套评估框架,分三个层次:
第一层:信息是否完整。这张图该有的节点有没有?该表达的连线有没有漏?读者看完能否拼出完整的闭环?这一层最容易自查,只要对着真实系统逐个比对就行。
第二层:结构是否清晰。关键路径能不能在三秒内被抓住?从起点到终点的主线是否一眼可辨?还是说盯着图找半天才能理出头绪?结构清晰取决于布局和分组,后面专门讲。
第三层:表达是否无歧义。相同含义是否总用相同符号?不同含义是否用了明显不同的视觉形式?有没有可能出现两种不同解读?这一层最难,因为作者太熟悉自己的设计了,总觉得"这还用说吗",但对读者来说歧义无处不在。
注意:一张图里,一种视觉形式只允许有一种含义,这条约束优先于任何美观考虑。
举个我踩过的例子。曾经画一张灰度发布流程图,我用同一种虚线同时表示"异步消息"和"可选分支"。结果评审会上,有人理解成"这两个分支都会异步执行",有人理解成"这是备选路径,多数情况不走"。同一条线两种读法,方案评审直接卡壳。后来我把语义拆开:异步用点虚线,可选分支用灰色实线,争论才消失。这个教训我一直记着:宁可图例多两行,也不要让读者猜。
2. 别急着动笔:先想清楚读者、决策和边界
画图的第一步永远不是打开画板,而是把三个问题写在纸上:这张图给谁看?他要做什么决策?信息边界画到哪里?很多图之所以画到一半推倒重来,就是因为第一步跳过了。
2.1 读者不同,同一套系统要画出不同的图
去年带新人时做过一个练习:给出一套系统的信息,让三个人分别画"系统架构图",用途分别是给决策层做预算审批、给新同事做入门理解、给值班同学做故障排查参考。结果三个人画出来的东西完全不同——这恰恰是对的。读者诉求拆开看是这样:
| 读者类型 | 核心诉求 | 应该突出什么 | 可以弱化什么 |
|---|---|---|---|
| 决策层 | 投入、风险、进度 | 模块边界、外部依赖、成本相关组件 | 内部调用细节、临时方案 |
| 执行层 | 自己的模块落在哪、跟谁交互 | 模块接口、依赖关系、改动影响面 | 部署拓扑、带宽容量 |
| 新同学 | 快速建立心智模型 | 分层关系、核心链路、数据流转 | 异常处理、边缘分支 |
| 值班同学 | 故障时快速定位 | 关键服务节点、监控接入点、依赖链路 | 业务细节、次要模块 |
你可能会说,这些图不都是同一套系统吗?对,但每张图回答的问题不一样。给决策层看的是"我要投多少钱、担什么风险",给新同学看的是"系统在逻辑上怎么组织",给值班同学看的是"哪里出问题了、该查哪个服务"。问题不同,画法自然不同。
这里有个反直觉的点:技术背景的同学画图时,总怕漏掉信息被说不严谨,于是拼命"画全"。但信息爆炸比信息缺失更难看。真正专业的做法是先做减法,把跟"要解决的问题"无关的节点收进附录。一张图的信息量,以目标读者一口能吃完为准。
2.2 一句话问题法:写不出来,就别画
我给自己立了个规矩:动笔前必须写出一句话——"这张图要回答什么问题"。比如:
- 这张图要回答:用户从登录到提交订单,经过哪些服务、每个服务做什么。
- 这张图要回答:当前模块重构后,依赖方向有没有出现反向。
- 这张图要回答:故障发生时,值班同学应该先看哪几个指标、按什么顺序排查。
能写出来,画图时就会自动聚焦;写不出来,说明你自己也没想清楚,这时候别硬画,先去做需求理解或方案梳理。很多人画到一半开始烦躁,本质上是目标问题不清楚,不知道该画到什么程度。
配套原则是:一张图只回答一个问题。如果一个目标问题还能拆出子问题,就拆成多张图。比如"系统整体长什么样"和"用户下单链路长什么样"是两个问题,拆两张图;宁可一组图配着看,也不要一张超载图让所有人找不到重点。多图组合的做法在第五节再展开。
2.3 一个主层次原则:部署视角和逻辑视角别混在一张图里
这是画架构图时最常见、也最容易被评审判死刑的错误。不少同学喜欢在一张图里既画"服务部署在哪台机器、哪个容器",又画"服务之间的逻辑调用关系"。结果画面上就会出现"线穿过边框"的诡异情景,因为逻辑调用关系跟物理位置本来就是两回事。
遇到这种图,我通常建议直接拆成两张:一张部署视图,回答"谁跑在哪、资源边界在哪";一张逻辑视图,回答"服务之间如何依赖、数据如何流转"。如果确实要放在一张图里,至少用明确的区域隔离两种语义,并配文字说明。一句话:一张图只维护一条抽象主线,这是 diagram-design 的底线之一。
拆开之后还有个好处:排查故障时,值班同学可以在逻辑视图上判断"该查哪个服务",再到部署视图上找"这个服务在哪个节点上重启",不用再在一张图里来回找。很多看似"省事"的合并,实际上是在给读者制造不必要的认知负担。
3. 三类高频图型逐个聊:关系流程、架构、时序
前面讲的都是普适原则。落到具体图型,每种图的画法和易错点都不一样。这里挑三类出现频率最高的:关系流程图、系统架构图、时序图,逐个展开。
3.1 关系和流程图:先把节点语义钉死,再说箭头
流程图是最常见的图,也是最容易被画成"乱线图"的类型。我建议至少遵守下面几条。
第一,节点语义要唯一。处理节点、判断节点、起止节点,在图上必须用不同形状表达,并且全图统一。更关键的是"语义和形状绑定":只要出现某个形状,读者就知道它是处理还是判断,绝不允许同一个形状在图上又表示操作、又表示存储。
第二,箭头要区分"控制流"和"数据流"。这是个高频坑。业务流程图里,"用户提交后系统处理"是控制流,"系统把订单数据写入数据库"是数据流。两种语义混在一个流程里时,建议用不同线型区分,或者把数据流单独抽成一张小图,避免主干线上挂一堆支线。
第三,判断分支必须有明确的出口标记。画判断节点时,每个出口必须标注条件,而且条件要互斥、要穷尽。比如"是否已登录",两个出口分别是"是"和"否",互斥且穷尽;如果画了第三个出口,必须确认真有第三个分支,不要无中生有。判断出口的箭头上只画线不写字,读者会绕晕。
第四,主线要少拐弯。流程主干最好从上到下或从左到右一路走到底,分支不要来回交叉。如果发现两条线交叉超过两处,说明布局或流程划分有问题——先调布局,调不动就考虑拆图。
我对流程图还有一个个人坚持:主干长度尽量控制在 7 个节点左右,最长不超过 12 个。超过这个数,普通人的工作记忆就撑不住了,读图需要反复回看。这时要么把细节折叠成子流程,要么拆成"总流程图 + 子流程"两张图。
3.2 架构图:分层、边界、依赖方向是三个固定动作
架构图的画法可以总结成三个动作:分层、画边界、定依赖方向。
先说分层。常规划法是自上而下分为接入层、应用层、数据层等大层次。分层的作用是让读者先建立整体纵览,再往下钻。层与层之间建议用水平方向的区域条带区分,层次标签写在左侧或条带内部。分层不是越多越好,三层能讲清楚的关系叠成七层,反而没人记得住。我的经验值是四到六层比较适合人脑理解。
再说边界。系统有系统边界,进程有进程边界,模块有模块边界。画图时,不同级别的边界用不同容器表达:系统边界用最大的外框加系统名,进程或部署单元用中框,模块用内层分组。边界线型也可以表达性质,比如虚线框表示"可选或计划中",粗线框表示"核心关键路径"。"边界画在哪"本身就是在跟读者确认系统切分逻辑,值得认真对待。
最后是依赖方向。架构图里箭头指向被依赖方,这是不能打破的约定。比如订单服务调用库存服务,箭头从订单服务出发指向库存服务。依赖方向乱掉,重构时容易出现循环依赖。我每次画完架构图都做一次循环检查:从任意节点出发沿着依赖箭头走,能不能走回自己?能走回,说明存在循环依赖,在图上用红色标出,跟方案一起评审。图阶段发现环,成本最低。
这里有个容易混淆的点:有些人把"调用方向"当成"业务数据流向",两者大部分时候一致,但也经常反向。比如数据上报系统,业务数据从采集端流向平台,但平台逻辑上未必依赖采集端,很可能是采集端依赖平台接口。所以画之前先明确:这张图的箭头表达的是"逻辑依赖"还是"数据流向"。一张图里只能选一种,两种都想表达就拆成两张,否则必乱。
提示:箭头语义(逻辑依赖还是数据流向)必须在图例里写明,评审时第一句话就确认这一点。
3.3 时序图:时间轴是铁律,"谁跟谁说话"才是主角
时序图在技术方案里出现频率很高,因为它能把"谁在什么时间调用了谁、返回了什么"讲得具体。画好时序图,我记住三件事。
第一,时间轴从上到下是铁律,代表"发生顺序",不允许跨轴回跳。如果需要表达循环或重试,用图上标注的方式说明,而不是让消息线回头穿过之前的区域——那样读者完全无法判断时序。
第二,参与对象要克制。时序图里每条竖线代表一个参与交互的对象。常见毛病是把所有类、所有服务都拖进来,甚至把数据库连接池也画一条线,结果一张图上百条线密密麻麻。我的建议是只保留"会发生消息交互"的参与者;那些不说话、不响应、纯存储的对象,要么合并,要么在文字说明里交代。画得好不好,有时就看你会不会舍弃。
第三,先列消息序列再画图。画时序图最忌讳打开画板边想边画。我会先在草稿纸上用文字列出消息序列,再落到图里。例如:
- 客户端调用登录服务的登录接口
- 登录服务校验后返回 token
- 客户端携带 token 调用订单服务的查询接口
- 订单服务返回订单列表
- 客户端渲染页面
这个习惯帮我挡掉了至少一半的时序混乱。另外给每条消息线标序号也很有用:多人评审时,"看第 4 条消息"比"最底下那个箭头的返回"精确得多,序号是讨论的唯一锚点。
4. 图面呈现的细节:布局、视觉编码和收尾
内容对了,还得让人愿意看、容易看。图面呈现这三层细节,是我最看重的部分。
4.1 布局:默认阅读顺序是从上到下、从左到右
人眼的阅读顺序不是随机的。中文语境下,从上到下、从左到右是默认扫描路径。因此图的布局应该顺着这条路径设计:起点在上方或左上,主线一路向右下延伸,不要逆着来。
具体操作上,我通常会注意几件事:
- 同层节点保持水平对齐。架构图里同一层次的节点,不管宽度差多少,顶边或中心线尽量对齐,视觉上立即清爽。
- 分组用留白或底色框,而不是只靠散点距离。只用间距做分组,稍微一拖动就散了;用明确的框或底色区域,分组关系才稳定。
- 主线尽量走直线,拐点越少越好。一个节点引出多个分支时,让分支朝同一方向展开,避免一根线绕三个弯。
- 交叉线是阅读的最大障碍。两条线交叉超过两处就要重新布局;实在无法避免,给线做颜色区分,或加跳线记号。
还有一个小设计点:长方形节点通常比正方形更好排版文字。因为阅读宽度天然是横向的,节点里的文本在长方形中换行次数更少,更容易扫读。我不是说正方形不能用,而是别为了"每个框一样大"硬凑成正方形,结果文字挤成一团。
4.2 视觉编码:颜色、线型、尺寸都必须承担含义
视觉编码指的是用颜色、线型、粗细、填充等视觉变量来表达信息。好的视觉编码只有一个标准:一次编码、全图统一、必须有图例。
颜色方面:如果要表达状态,建议使用行业直觉色,绿色表示成功或可用,红色表示异常或危险,黄色表示告警或待确认。但有两个禁忌。一是别只靠颜色表达,要考虑色弱读者和黑白打印,颜色必须配合文字标签或形状;二是别把颜色当装饰,为了区别而给并列模块刷彩虹色,只会增加读者的记忆负担。
线型方面:实线通常表达强关系或同步调用,虚线表达弱关系或异步、可选,点线可以表达消息或临时路径。但同一套系统文档里,线型语义必须跨图保持一致。我见过一份文档里,红色虚线一会儿表示"异步消息"一会儿表示"故障转移",直接把读者绕晕。
尺寸方面:节点大小通常承载两个含义,一是重要性,二是容量规模。我的建议是大小差异要有度,最大的节点不要超过最小节点的三倍,否则视觉上小的节点会被直接无视。想让某个节点突出,优先用边框加粗或填充颜色,而不是无脑放大。
最后,只要图上出现了任何非默认视觉语义,图例必须出现在角落。图例不是可选项,它就是私有协议公开化的唯一手段。我见过太多精美好看的图,追着问三个问题才发现颜色、线型全都没定义。这种遗憾,一个角落的图例就能避免。
4.3 收尾工作:对齐、标注、编号和版本
画完主体后,不要急着截图交付。最后十分钟的收尾,决定了这张图是被认真对待还是被随手划过。
先做基础检查:所有节点对齐、间距统一、文字完整无重叠、箭头方向一致。这些细节单独看不致命,合在一起就是"专业感"。我自己有个土办法:把图缩到 50% 大小眯着眼看。如果缩放后还能清晰分辨结构和主线,说明布局及格;如果缩到一半就糊成一团,说明连线太乱或信息过载,需要返工。
注意:图缩到 50% 依然结构清晰,是布局及格线的低成本检验方式。
再做信息标注:图上最好给关键节点编稳定编号。评审时说出"A2 节点"比用手指戳屏幕效率高得多。编号同时是跨文档引用的桥梁:"结构见架构图节点 A2",读者能立刻定位。
最后是版本信息:图脚或右下角写上标题、日期、作者、版本号。这一步很多人嫌麻烦,但它救过我很多次。项目周期里一张图被改七八版是常态,没有版本号,两周后你自己都说不清屏幕上这张对应的是哪版代码。
5. 沉淀下来的一套自检清单:画完照着过一遍
前面讲了很多原则,单靠记忆容易漏。我在团队里推行的做法是,把原则固化成一页自检清单,画完图逐项打勾。别嫌这步教条,代码有 lint,图也必须有 lint。
5.1 单图自检的十项检查
| 检查项 | 不过关的信号 | 修正动作 |
|---|---|---|
| 目标问题明确 | 说不清这张图回答什么问题 | 回退到一句话问题法 |
| 读者明确 | 不知道给谁看 | 确认受众,调整信息密度 |
| 抽象主线唯一 | 部署和逻辑混在一个平面 | 拆成部署视图 + 逻辑视图 |
| 节点语义统一 | 相同形状两种含义 | 统一形状约定并写进图例 |
| 连线语义统一 | 同一种线型两个含义 | 拆分语义或新增线型并补图例 |
| 箭头方向明确 | 逻辑依赖和数据流向混淆 | 确定箭头语义,全图遵守 |
| 主线清晰 | 三秒内找不到关键路径 | 调整布局,减少交叉 |
| 图例完整 | 颜色和线型无解释 | 补图例,放在角落 |
| 编号可引用 | 讨论时无法定位节点 | 关键节点加编号 |
| 版本信息完整 | 无日期无版本号 | 补右下角版本角标 |
这张表我几乎每两三个月更新一次,每次都是因为踩了新的坑,把坑补进去。你可以按自己的场景增删,重点不是条数,而是"画完过后有人会真的去检查"。
5.2 多图组合时的全局一致性
单图画好了,还要看文档里一组图能不能一起讲一个故事。多图设计里我最在意两件事。
第一是跨图一致性。颜色、线型、编号规则必须在一整套文档里保持一致。比如这套文档里红色在架构图里表示异常,在流程图里突然变成"重点模块",读者就会被误导。维护一份团队级"绘图约定手册",把所有符号语义写在一起,新老成员都按它来。
第二是图与图之间的引用脉络。复杂系统建议按"总览图 → 局部图 → 细节图"组织。总览图只画关键模块和主干依赖,局部图对单个模块展开,细节图才出现接口和类级别信息。每张局部图上注明"本图是总览图第二个节点的展开",读者就有了阅读路线。没有这种脉络的文档,往往是几十张平行排列的图堆在一起,看的人根本不知道该先看哪张。
5.3 图会"腐烂":从画图到养图
技术文档里最常见的问题是图与真实系统脱节。代码每天都在变,图还停留在三个月前,最后大家都默认"图不可信,看代码去"。一旦这种认知形成,前面所有的图全白费了。
我的经验是把图当作代码一样管理,给它一个生命周期:
- 变更请求动到某个模块时,要求图中同步更新,并且尽量"先改图、再改代码",至少要在同一次提交里一起改。先改图的额外好处是,逼你思考清楚再动手写实现。
- 图中标注"最近更新时间"。哪怕不能保证全量更新,至少读者知道这张图的时效性。
- 给新人留一个入口:凡是看不明白的地方,直接在图上标记。每周花十五分钟过一遍新人提出的疑问点,把被问得最多的位置优先修掉。
- 每次架构评审,顺手把"图与实现是否一致"列为检查项。坚持两三次,团队就养成了同步习惯。
这条我体会特别深。以前带项目时不重视,三个月后图废了,方案评审时大家对着旧图讨论新系统,浪费了大量时间。现在把"养图"放进流程,每次只多花几分钟,省掉的返工时间远不止这个数。
6. 工具选型与多人协作:真问题从来不在软件上
最后聊聊工具和协作。很多人在"用哪款绘图软件"上花半天纠结,我的看法是:工具只是载体,真正的生产瓶颈是约定和管理方式。工具选型只要能满足三个基本条件——多人可访问、支持导出、格式稳定可追溯——剩下的差异都可以用工作方式弥补。
6.1 三类主流工具形态的取舍
按经验,绘图工具可以粗略分成三类,各有适用场景。
第一类,在线白板类。优势是实时协作、发散自由,适合方案讨论、头脑风暴阶段。劣势是自由度太高,线条容易乱飞,很难形成整洁的正式交付物。用这类工具画出的东西,通常需要在收敛后重画一遍。
第二类,桌面矢量绘图类。优势是精细控制、排版能力强,适合最终交付的架构图和流程图。劣势是多人同时编辑麻烦,版本管理基本靠手工,文件导来导去容易出多份副本。用这类工具,一定要把"唯一主副本"的位置定清楚。
第三类,基于文本描述的绘图类。用写代码的方式描述节点和连线,工具负责生成图。优势是天生适合版本管理,提交时可以看差异,图随代码走,不会腐烂。劣势是排版自由度低,不适合快速发散。这类工具很适合把图纳入持续集成的场景,每次提交自动重新生成文档。
我的习惯是"白板发散、矢量定稿、文本入库":讨论先在白板上快速验证思路,确认后再出正式图用于评审,最后把图的源文件或文本描述提交进文档仓库,保证可追溯。
6.2 多人协作时最常见的三类冲突
工具定了,人齐了,协作问题才开始。我见过最多的三类冲突是:
格式冲突。每个人画图习惯不同,图例不统一。解决方式是从团队层面定一份"绘图约定"文档,明确颜色、线型、节点形状的语义。这份文档本身也可以配一张示例图,比纯文字说十句都管用。
编辑冲突。两个人同时改一张图,互相覆盖。解决方式是明确每张图的 owner,改图先经过 owner,或者至少改完在群里知会一声。有个细节容易被忽略:在线工具虽然支持多人实时编辑,但"实时编辑"不等于"同时写同一张图",没有分工照样冲突。
过期冲突。图和实现脱节,谁也不信任谁。这个问题的解法在第五节"养图"里已经讲过,核心是让图跟变更流程绑在一起,而不是靠自觉。
6.3 一个多年实践后留下来的小习惯
最后分享一个自己用了很久的习惯:每张图右下角,除了版本号,还会留一行小字——"这张图回答什么问题"。别小看这行字,它强制我在交付前重新确认图的定位。画的时候它是目标约束,发出去之后它是读者的阅读指引。有次评审,对方第一句就问这行小字是什么意思,我顺势解释了图要解决的问题,整场评审的节奏立刻顺畅很多。
另外,在方案文档里我坚持"图、表、文"三层配合:图给全景和结构,表给数据和参数,文给结论和依据。要求一张图承担所有信息,是画图者最常犯的贪心错误。把信息分层,每张图只做它最擅长的事,整个方案的可读性和可信度都会上一个台阶。
画图这事儿,做久了你会发现,它考验的从来不是美术天赋,而是对问题的理解、对读者的尊重和对约定的坚持。以上都是我用实际踩坑换来的体会,不一定适合所有人,但胜在能给你一个起点。从下一张图开始,试着先写出一句话问题,再把图例补全。你大概率会发现,评审时被追问的次数,会肉眼可见地变少。