系统分析师实测:PlantUML凭什么赢过Mermaid!

画图如写诗,别让工具偷走你的叙事权!

把你辛辛苦苦梳理的业务逻辑交给一个“猜你喜欢”的渲染引擎,这事儿本身就离谱!


Mermaid凭借“开箱即用”的便利性横扫GitHub README和各类技术文档,而PlantUML则靠着对UML标准的死磕和对细节的绝对掌控,在系统分析师和架构师圈子里稳坐江山。这场持续多年的“代码即图表”工具之争,表面上是语法繁简的对决,实则是两种哲学观的正面碰撞——你愿意为了五秒钟的上手速度,牺牲掉对最终产物的那怕一丝控制权吗!

那个让你抓狂的“一步错步步错”的垂直间距

打开Mermaid的时序图编辑器,写下几个参与者和消息流,渲染出来的图干净、现代、看着挺像那么回事。直到你发现——某条消息的标签贴得太紧,都快跟箭头黏在一起了。

你想加个空行。就一个空行。局部的、精准的、只让这一个元素喘口气的空行。

Mermaid的答案是:不行。

你能做的只有两件事。一是用
标签硬生生把标签往下推——这本质上是在用HTML hack来弥补布局引擎的缺陷。二是调整全局的boxMargin参数,让整张图的所有元素一起膨胀。你要的是给一棵树浇水,它给你的是把整片森林淹了。

这就好比你写Word文档,想在某一段后面多加一行空行,结果整个文档的行距全部翻倍。你确定这是“自动化”而不是“自动添乱”?

PlantUML的处理方式就简单粗暴得多——在需要加空行的位置塞一个|||。就三个竖线。不多不少。精确命中目标。你想在哪加就在哪加,想加多少就加多少。

这不是什么高级功能。这只是一个渲染引擎该有的基本素养——听懂人话,指哪打哪。对吗!

那个让你欲哭无泪的“五彩斑斓”的视觉定制

系统分析师画时序图,从来不是为了好看。是为了让看的人一眼就能分清——哪条是主路径,哪条是异常分支,哪个环节可能会出问题。

我见过的最实用的做法:用浅红色标记所有错误处理流程。整张图扫过去,红色路径就是“千万别走这条”的警示灯。信息密度直接拉满。

Mermaid说:对不起,做不到。

你可以在全局层面选一个主题——暗色、亮色、森林、或是某个让你怀疑设计师色盲的“酸系”配色。但你想单独给某一个激活框换个颜色?想区分主流程和嵌套流程的视觉层级?想用颜色本身传递语义信息?

Mermaid的渲染引擎会一脸无辜地看着你:要不……您再考虑一下全局主题?

更让人血压飙升的是那些小bug。自调用(self-call)的消息标签,Mermaid会给你居中对齐到参与者的生命线上——而不是箭头本身。激活框会莫名其妙地贴着其他形状的边框,像两个挤地铁的陌生人。你稍微动一下主题配置,整张图可能直接变成一场视觉灾难——据说有人不小心触发了某种“酸系”特效之后,就再也没碰过Mermaid的样式定制功能。

PlantUML的skinparam系统则像是一个严谨的工匠——你想改颜色就改颜色,想调字体就调字体,想给不同的激活框配不同的背景色?没问题。它把控制权交到你手里,而不是让一个“智能”的渲染引擎替你猜。

那个让你怀疑人生的嵌套激活

这是最致命的一刀。

时序图里的嵌套激活(nested activation),说白了就是“A调用B,B又调用了C”——这种三层甚至更深层次的调用关系。系统分析师画这种图的时候,往往是在处理一个黑盒:我知道外部调了内部,但内部具体怎么运作的,我不需要、也不应该在图上瞎猜。嵌套激活框就是用来“折叠”这些未知细节的——一个框套一个框,层次分明,谁调用谁一目了然。

Mermaid处理这个场景的方式,堪称行为艺术。

第一步:你写了一个自调用,同时已经有一个激活框开着。Mermaid不给你创建新框,而是把现有的那个框往下挪了挪——箭头从框外面射进去,而不是从框里面射出来。

第二步:你绝望了,在下一行写了一个deactivate——按理说没有对应的activate,这代码应该报错才对。但Mermaid偏偏在这时候“变”出了一个嵌套框。恭喜你,魔法生效了!

第三步:你定睛一看——箭头还是插在原来的外层框上,而不是新建的那个内层框里。

结果就是一张充满“解读空间”的图。而一张图的职责,恰恰是消灭解读空间。

PlantUML的表现则是教科书级别的——嵌套框老老实实地叠在父框里面,箭头精准地指向对应的执行层级。你写什么,它渲染什么。没有惊喜,没有惊吓,没有“Mermaid你猜我想干什么”的猜谜游戏。

那个被狂热追捧却始终“差点意思”的生态王者

说到这里,必须承认一个事实:Mermaid的生态优势是碾压级的。

GitHub原生渲染——你在README里写一个mermaid代码块,它自动变成图表。没有插件,没有构建步骤,没有“图片没更新”的困扰。Notion支持、Obsidian支持、GitBook支持、几乎所有静态网站生成器都支持。你甚至可以在ChatGPT的对话框里直接生成Mermaid图表。

PlantUML呢?需要Java运行时,需要Graphviz做布局渲染,需要额外的插件或者CI构建步骤。在GitHub上,它只能以图片形式存在,没法像Mermaid那样“活”在Markdown里。

单看这些,Mermaid赢麻了。

但问题在于——当一个工具90%的使用场景是“画个简单流程图放进README”,它的开发者会把多少精力花在“时序图的嵌套激活渲染逻辑”上?答案是:不会太多。

Mermaid的定位从一开始就是“轻量级”“够用就好”。它要服务的是几百万个写README的开发者,而不是几百个画复杂系统时序图的系统分析师。这不是对错问题,是取舍问题。

但你作为那个需要画复杂时序图的人,你愿意为了“GitHub原生渲染”这一个便利,忍受上面所有那些糟心事儿吗?

那个“默认效果足够好,你不需要调”的新玩家

就在Mermaid和PlantUML打得难解难分的时候,一个叫D2的新工具悄悄冒了出来。

D2的卖点很直接——布局质量。它的约束式布局引擎产出的图表,默认效果就比Mermaid和PlantUML干净一大截。当Mermaid的布局给你一团乱麻的时候,D2的自动排版像是真的读懂了你的心思。

但D2也有自己的问题——图表类型覆盖比PlantUML窄得多,生态还很年轻,编辑器插件少得可怜。而且,怎么把D2画的图嵌进Confluence——据说这是一门只有少数“天选之人”才掌握的秘技。

所以现在的情况是:Mermaid赢在普及度,PlantUML赢在专业度,D2赢在布局质量。三足鼎立,各有所长,也各有所短。

为什么我还在用那个“老古董”

我每隔半年左右会给Mermaid一次机会。打开Mermaid Live Editor,写一段时序图,看看它的渲染有没有进步。

确实有进步。消息标签的对齐方式可以调了。Live Editor比两年前稳定多了。GitHub上的一些issues已经被标记为“已规划修复”。

但这些进步,都没有触及最核心的问题——Mermaid的渲染引擎在替我做决定。它决定我的间距该多大,我的颜色该多单调,我的嵌套框该歪到哪里去。

而PlantUML把决定权还给了我。

这不是什么“老派”vs“新潮”的品味之争。这是“工具替你工作”和“工具替你决策”的本质区别。Mermaid说“我帮你画好”,PlantUML说“你告诉我怎么画”。

对于README里的流程图,前者够了。对于系统分析师手里那张承载着几十个接口调用关系、错误处理分支、超时重试逻辑的时序图——后者才是唯一答案。

那张永远对不齐的激活框

上个月我帮一个团队 review 他们的API文档。他们用Mermaid画了一张支付流程的时序图——七个参与者,四层嵌套调用,三个alt分支。

图看起来挺漂亮。直到有人问了一句:“这个activate框到底是从哪里开始、到哪里结束的?”

没人能回答。

箭头插在框外面。嵌套框和父框的边界糊在一起。消息标签和箭头之间的距离,有的紧贴、有的悬空,全看Mermaid的渲染引擎当天心情如何。

他们把图改了四遍。每次都是“差不多行了”。

最后换成PlantUML重画了一遍——同样的逻辑,同样的参与者,同样的嵌套层级。出来的图,每一根箭头都插在它该插的地方,每一个框都叠在它该叠的位置,每一条消息的间距都整整齐齐。

团队里一个刚入职的开发说了一句:“原来这张图讲的是这个意思啊。”

他之前看了四遍Mermaid的版本,都没看懂。

这就是差距。