资讯动态

Diagram as Code:让技术架构图与代码同步的工程实践

发布时间:2026/10/26 19:36:44 来源:尧图企业网站定制
1. 从“diagram-design”这个标题说起它到底在解决什么问题第一次看到“diagram-design”这个标题很多人会下意识觉得它是个设计工具或者某个绘图库的名字。但如果你真的在工程团队里待过就会明白这个词背后藏着的是一类非常具体的痛点技术方案讲不清楚、系统结构画不明白、跨团队沟通时每个人脑子里的架构图都不一样。我在过去几年里参与过不少系统重构和架构评审最深的感受就是——代码写得再漂亮如果图画不明白评审会上照样被问得哑口无言。而“diagram-design”这个主题本质上要解决的就是三件事第一如何用一套可维护的方法把系统结构可视化第二如何让图跟代码保持同步而不是画完就过期第三如何让不同角色开发、测试、运维、产品看到同一张图时能达成一致理解。这篇文章适合谁看如果你是被架构图折磨过的后端开发、需要写技术方案的技术负责人、或者正在做系统设计文档的工程师那接下来的内容应该能帮你省下不少返工时间。我不会只讲“用什么工具画图”而是会把图背后的设计逻辑、常见踩坑点、以及怎么让图真正服务于工程实践讲透。需要先说明一点本文讨论的“diagram-design”不绑定任何特定商业工具重点在于方法论和落地路径。工具会过时但“怎么把复杂系统拆成可表达的图形语言”这件事是每个技术人都绕不开的基本功。2. 为什么大多数技术架构图活不过三个月2.1 图与代码脱节的根因不在工具在流程我见过太多团队在项目启动时花两天画了一套精美的架构图然后随着迭代推进图上的模块名改了、接口变了、新增的服务没补上去三个月后这张图就变成了“历史文物”。很多人把这个问题归咎于“工具不好用”或者“大家不够重视”但真正的根因其实是图的更新没有嵌入到开发流程里。你想想代码变更时有CI流水线卡着有code review兜底有测试用例验证。但图呢图改了没人知道图没改也没人发现。它游离在工程流程之外自然就会腐烂。所以“diagram-design”的第一个核心原则就是图必须和代码一样有明确的owner、有变更触发机制、有审查环节。具体怎么做我的做法是把架构图拆成两类一类是稳定层图比如系统上下文图、领域划分图这类图变更频率低可以按季度review另一类是易变层图比如服务调用关系、数据流向图这类图必须跟代码仓库绑定代码合并时如果涉及接口变更PR里必须同步更新对应的图。2.2 “画得好看”和“画得有用”是两回事刚入行的时候我也追求过图的视觉效果配色、图标、阴影都抠得很细。后来发现评审会上真正被追问的从来不是“这个圆角好不好看”而是“这个箭头代表同步调用还是异步消息”“这条线走的是内网还是公网”“这个模块挂了会影响哪些上游”。所以diagram-design的第二个原则是图的表达力优先于美观度。一张好的技术图应该能在30秒内回答三个问题——系统边界在哪、关键依赖是什么、故障影响范围有多大。至于配色能用黑白灰加一两个强调色解决的就不要搞彩虹色。这里有个实操建议画图时先不要打开工具拿张白纸把“必须表达的信息”列出来。比如系统与外部交互方的边界核心数据存储及其归属同步/异步通信路径关键组件的部署单元故障域和降级路径列完之后再选图形元素去映射这些信息而不是先选工具再想画什么。2.3 不同角色看同一张图关注点完全不同这是最容易被忽略的一点。开发看架构图关注的是“我负责的模块跟谁交互”运维关注的是“这个服务部署在哪、依赖什么中间件”测试关注的是“哪些路径需要覆盖”产品关注的是“用户请求经过哪些环节”。如果只用一张图应付所有人结果就是每个人都觉得“这图跟我没关系”。我的经验是采用分层视图策略视图层级目标读者核心表达内容更新频率上下文视图全员系统边界、外部依赖低容器视图开发/运维服务划分、技术选型中组件视图开发模块职责、接口关系高部署视图运维节点分布、网络分区中数据流视图开发/测试数据走向、状态变更高这套分层思路借鉴了C4模型的理念但我不建议照搬它的全部符号体系因为团队里真正愿意学一套新符号的人不多。关键是分层的思想而不是具体的画法。3. 把图当代码管diagram-design的落地方法论3.1 用文本描述图而不是用鼠标拖拽如果你还在用拖拽式工具画架构图我建议认真考虑切换到Diagram as Code的方式。原因很简单文本可以进版本控制、可以做diff、可以review、可以自动生成。拖拽出来的二进制文件做不到这些。目前主流的文本化绘图方案有几类我按适用场景做个对比方案类型典型代表适合场景学习成本版本控制友好度声明式DSL结构化描述语言架构图、流程图中高代码生成从代码注解生成调用关系图低极高图表库编程语言绘图库定制化图表高高混合方案DSL渲染引擎复杂技术图中高高我自己的选择是架构类图用声明式DSL调用关系用代码生成数据流图用DSL加自定义样式。这样既保证了可维护性又不会因为过度自动化而失去表达灵活性。举个具体的例子用声明式方式描述一个服务依赖关系大概长这样services: api-gateway: depends_on: - user-service - order-service protocol: http sync: true user-service: depends_on: - user-db protocol: tcp sync: true order-service: depends_on: - order-db - message-queue protocol: mixed sync: false这段描述渲染出来就是一张清晰的服务依赖图。关键在于当user-service新增了一个依赖时你只需要在YAML里加一行CI流水线就能自动更新图并推送到文档站点。整个过程不需要人工打开绘图工具。3.2 让CI流水线帮你检查图的“新鲜度”光有文本化还不够还得有机制保证图不会过期。我的做法是在CI里加一个检查步骤如果代码中的接口定义发生了变化但对应的图描述文件没有更新流水线就报warning。具体实现思路是从代码的接口定义文件比如OpenAPI spec、gRPC proto、或者代码注解中提取服务依赖关系然后跟图描述文件里的依赖做比对。不一致就提示“检测到依赖变更请更新架构图”。这个检查不需要做到100%精确哪怕只能覆盖核心服务的依赖关系也能拦住大部分“改了代码忘了改图”的情况。我实测下来加了这道检查之后架构图的平均过期时间从三个月延长到了半年以上。注意这个检查步骤建议设为warning而非error否则容易因为误报导致开发反感反而推动不下去。先让大家养成习惯再逐步收紧。3.3 图的评审应该跟代码评审合并很多团队把架构图评审搞成一个单独的会议结果就是大家都不愿意参加。我的建议是把图的变更放到代码PR里一起review。具体做法是当PR涉及服务接口变更时要求作者同时更新图描述文件reviewer在看代码diff的同时也能看到图的diff。这样做有几个好处第一图的变更有了明确的上下文reviewer知道为什么要改第二图和代码的变更原子性提交不会出现“代码合并了图还没改”的中间状态第三降低了单独组织图评审的沟通成本。当然这要求图描述文件和代码在同一个仓库里或者至少是同一个PR能覆盖的范围。如果图放在独立的文档仓库可以考虑用submodule或者CI触发的方式关联起来。4. 画图时最容易踩的五个坑4.1 把“部署图”和“架构图”混在一起画这是新手最常犯的错误。部署图关注的是“进程跑在哪台机器上、网络怎么分区”架构图关注的是“模块之间怎么交互、职责怎么划分”。把两者混在一起结果就是图上一堆服务器图标和网络连线但真正的业务逻辑关系反而看不清了。我的做法是严格分开架构图里不出现具体的IP、端口、节点数量部署图里不出现业务模块的职责描述。两张图通过服务名这个共同标识关联起来。需要看全貌时把两张图并排放在一起看。4.2 箭头方向不一致导致理解混乱有的图里箭头表示“调用方向”有的图里箭头表示“数据流向”还有的图里箭头表示“依赖方向”。如果一张图里混用了多种语义读图的人就会疯掉。我的建议是一张图里只允许一种箭头语义。如果是调用关系图所有箭头都表示“谁调用谁”如果是数据流图所有箭头都表示“数据从哪流到哪”。如果确实需要表达多种关系就用不同的线型实线/虚线加图例说明但语义必须统一。4.3 忽略“非功能”信息的标注很多架构图只画了功能模块和调用关系但完全没标注超时时间、重试策略、熔断阈值这些非功能信息。结果就是开发照着图实现了调用但线上出了问题才发现“原来这个调用没有配超时”。我的经验是在关键的调用链路上标注SLA和降级策略。比如在服务A到服务B的连线上标注“timeout3s, retry2, fallback缓存”。这些信息不需要每一条线都标但核心链路必须标。这样图就不只是“结构说明”而是“设计约束”的载体。4.4 图例缺失或图例与实际不符我见过太多图画了一堆不同形状的框和不同颜色的线但没有任何图例说明。或者有图例但图例里写的是“蓝色数据库”实际图上蓝色框画的是缓存。这个问题看似低级但出现频率极高。我的做法是图例必须跟图一起review图例变更必须跟图变更一起提交。如果用的是文本化绘图方案图例本身也是代码的一部分天然就能保证一致性。4.5 一张图塞太多信息人的短期记忆容量有限一张图上如果超过15个元素理解成本就会急剧上升。我见过一张“大而全”的架构图上面有40多个模块和上百条连线结果就是没人愿意看。正确的做法是按关注点拆分。比如把“用户请求链路”和“后台定时任务链路”拆成两张图把“核心交易流程”和“辅助管理流程”拆成两张图。每张图只回答一个核心问题信息密度控制在合理范围内。5. 从零搭建一套可持续的diagram-design体系5.1 第一步盘点现有图资产该扔的扔如果你所在的团队已经积累了一堆架构图第一步不是急着画新图而是盘点旧图。把现有的图过一遍按“是否还在用”“是否还准确”“是否有人维护”三个维度分类。我的经验是一个中等规模团队的历史架构图里大概有60%已经过期或无人维护20%只有部分准确真正能用的不到20%。对于过期且无人维护的图果断归档或删除不要舍不得。留着只会干扰后来人。盘点的时候顺便记录一下哪些图是大家真正会去看的哪些图是画完就没人碰过的这个信息对后续决定“哪些图值得投入维护”非常关键。5.2 第二步确定图的分类体系和命名规范盘点完之后需要建立一套图的分类体系。我建议按“视图类型系统名版本”来命名比如context-payment-system-v2container-order-service-v1deployment-user-center-v3命名规范看起来是小事但当图的数量超过20张之后没有规范命名就会变成灾难。搜索的时候找不到、引用的时候说不清、归档的时候理不顺。分类体系不需要太复杂关键是团队内达成一致并写进文档。新来的同学照着规范就能知道该把图放哪、该叫什么名字。5.3 第三步选一套文本化工具链并统一工具选型的原则是团队里大多数人能在半天内上手且能进版本控制。不需要追求功能最强大的而是要选学习成本最低、跟现有流程最容易集成的。我一般会推荐这样的组合用声明式DSL描述图结构用渲染引擎生成图片用CI流水线自动构建和发布。具体选哪个DSL和哪个渲染引擎取决于团队的技术栈和文档平台。关键是统一不要这个项目用一套、那个项目用另一套。选好之后写一份简单的“画图指南”包含怎么创建新图、怎么本地预览、怎么提交变更、怎么发布。这份指南不需要很长一页纸就够但必须让每个人都能找到。5.4 第四步把图的维护写进Definition of Done这是最关键的一步。如果图的维护只是“建议”而不是“要求”那它永远排不上优先级。我的做法是把“更新相关架构图”写进团队的Definition of Done里跟“补充测试用例”“更新接口文档”并列。具体执行时在PR模板里加一个checkbox“本次变更是否涉及架构调整如果是是否已更新对应架构图”reviewer在review时检查这个checkbox。一开始可能会有人漏掉但坚持几周之后就会形成习惯。提示不要一开始就追求100%覆盖先从核心服务开始跑通流程后再逐步扩大范围。步子太大容易扯着。6. 几个真实场景下的diagram-design实践6.1 场景一新服务上线时怎么画图新服务上线是最需要画图的场景因为这时候大家对它的结构最陌生。我的做法是先画上下文图再画容器图最后补部署图。上下文图回答“这个服务跟谁交互”容器图回答“这个服务内部有哪些模块”部署图回答“这些模块跑在哪”。三张图画完一个新同学就能对这个服务有完整的认知。这里有个技巧上下文图里的外部依赖要标注“是否核心依赖”。核心依赖挂了服务就不可用非核心依赖挂了可以降级。这个信息在故障排查时非常有用。6.2 场景二系统重构时怎么用图对齐认知系统重构最怕的就是“每个人脑子里的目标架构不一样”。这时候图的作用不是“描述现状”而是“对齐目标”。我的做法是在重构启动会上让每个核心成员各自画一张“我认为重构后应该是什么样”的草图然后放在一起对比。差异最大的地方往往就是认知最不一致、最需要讨论的地方。讨论达成一致后再画一张正式的“目标架构图”作为重构期间的参考基准。重构过程中如果发现目标需要调整图也跟着调整保证图始终反映最新的共识。6.3 场景三故障复盘时怎么用图定位问题故障复盘时一张清晰的调用链路图能极大提升效率。我的做法是在复盘会上把故障时间段的调用链路图投出来沿着出问题的链路一步步走。这时候图的价值不在于“画得对不对”而在于“能不能快速定位到出问题的环节”。如果图上的调用关系跟实际不符那说明图需要更新如果图上是异步调用但实际是同步那说明标注需要修正。每次故障复盘之后我都会检查一下相关链路的图是否需要更新。这样图就在一次次实战中变得越来越准确。7. 关于diagram-design我踩过的最大的一个坑说了这么多方法论最后分享一个我自己踩过的坑。早期我特别迷信“自动化生成架构图”觉得只要从代码里自动提取依赖关系就能一劳永逸地解决图过期的问题。结果做了半年之后发现自动生成的图确实不会过期但它只反映了代码层面的调用关系完全丢失了设计意图。比如代码里服务A调用了服务B但为什么要调用、这个调用是核心链路还是辅助链路、超时和降级策略是什么这些信息代码里没有自动生成的图里也没有。后来我调整了策略自动生成负责“准确性”人工标注负责“表达力”。自动生成提供基础的依赖关系骨架人工在骨架上补充设计意图、SLA、降级策略等关键信息。两者结合既保证了图不会跟代码脱节又保证了图能表达出代码之外的设计决策。这个坑让我明白一个道理diagram-design的核心不是“画图”而是“把设计决策显性化”。图只是载体真正有价值的是图背后那些“为什么这样设计”的思考。如果只追求图的自动更新而忽略了设计意图的表达那就是舍本逐末了。另外还有一个实操层面的小教训不要试图用一套图满足所有场景。我曾经想设计一套“万能架构图模板”结果发现不管怎么调整总有人觉得“我要的信息没有”。后来放弃了万能模板的想法改为针对不同场景设计不同的图反而大家都觉得好用了。如果你刚开始搞diagram-design我的建议是从一张图开始先把一个核心系统的上下文图画清楚让团队里的人都来看、都来提意见。一张图跑通了再推广到其他系统。不要一上来就搞大而全的体系那样大概率会半途而废。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑