电商领域模型
顾客、地址、订单、订单项、商品、支付,外加一个状态枚举 —— 任何一条下单链路背后都是这几个名词。做交易类产品的常规起点。
7 个类 · 6 条关系
8 张画得很满的类图。打开就在画布上。然后把它聊成你自己的系统:「把 Payment 删掉、Member 改名叫 Subscriber、Repository 改成接口」。
这里每张图都和你导入后拿到的出自同一份结构化定义 —— 没有一张是精修过的截图。卡片上的预览只画类和关系,这样缩到卡片大小还看得清结构;点开任意一张能看到完整版,字段和方法一个不少。「进对话微调」把图放进画布并打开对话面板,你的第一句话就能开始改它;「用这个模板」只把它放进编辑器,剩下的你自己来。
顾客、地址、订单、订单项、商品、支付,外加一个状态枚举 —— 任何一条下单链路背后都是这几个名词。做交易类产品的常规起点。
7 个类 · 6 条关系
每次安全评审都要在白板上重画一遍的那张:用户挂角色,角色发权限,会话会过期,再用一个策略接口把鉴权实现留成可替换的。
7 个类 · 6 条关系
书和「实体副本」分开,加上借阅、预约、罚金。不用编玩具领域,就能把聚合和组合摆在同一张图里讲清楚。
7 个类 · 8 条关系
一个接口,三个可互换的实现,外加一个工厂。评审的人还没读方案正文,看见这个形状就知道你要说什么。
7 个类 · 6 条关系
抽象方法、覆写、两级层次,再加一个 Drawable 接口。讲继承本身可以用它,做任何多态设计也可以拿它当骨架。
8 个类 · 7 条关系
控制器依赖服务,服务只认接口,每个接口各有两个实现。想把「依赖倒置」讲明白,画这张比写三段话管用。
9 个类 · 8 条关系
文章、版本、作者、分类、标签、评论、素材 —— 内容型产品在写第一个 migration 之前必须先定下来的那张多对多关系网。
7 个类 · 7 条关系
发布方完全不知道订阅方是谁。写事件总线、钩子,或者代码里任何叫 listener 的东西时用得上。
8 个类 · 7 条关系
有点反直觉但确实好使:选类比你需要的更多的模板。看着图删掉一个类是两秒钟的事,而想起来「漏画了一个类」得再走一轮评审。
页面加载完图就在画布上,可见性标记、基数、接口、六种箭头全都已经就位。
打开对话面板,用句子纠正它:「把 Payment 删了、Member 改名叫 Subscriber、Repository 改成接口、Team 到 Project 加一条所有权关系」。助手改的就是你眼前这张结构化的图,所以每一轮返回的是重画后的版本,而不是重新猜一张。
分屏视图把 Mermaid 源码和预览摆在一起,做最后几处微调。然后:文档里会被放大的用 SVG,幻灯片和工单用 PNG,或者把源码提交到它描述的那段代码旁边。
UML 类图讲的是系统的结构:有哪些类型、每个类型存什么数据、暴露什么方法、彼此之间怎么连。它回答的是「这个系统由什么组成」,而不是「用户点了下单之后依次发生了什么」—— 后者是时序图的活。
工程上最常用在三个地方:新人文档,一张图省掉一下午读 model 的时间;技术方案,一套还没写的类层次得先被吵一遍;重构计划,前后两张图摆一起,破坏性改动藏不住。
Mermaid 的 classDiagram 覆盖了工程文档里真正会用到的记号 —— 可见性标记、<<interface>> 和 <<abstract>> 这类构造型、泛型、基数,以及全部六种关系箭头。它不是完整 UML:没有泳道,也没有活动图语义。对大多数文档来说这是好事,不是缺口。
类的方框分三格,只有第一格是必须的 —— 一个既没属性也没方法的类完全合法,先把关系连出来、细节回头补,是很常见的画法。
泛型用波浪号而不是尖括号 —— List~Order~ 会渲染成 List<Order>。方括号的数组写法不在语法里,统一用波浪号那种。
类图的信息量几乎全在这六根箭头上。画对了图就是设计文档,画错了它会悄悄说出一个你没打算说的意思 —— 评审的人是真的会看那个菱形是实心还是空心。
<|--实线加空心三角,三角指向父类。子类是父类的一种,继承它的属性和方法。在对话里说「Dog 继承 Animal」,出来的就是这根箭头。
<|..虚线加空心三角。类实现了别处声明的契约 —— 接口或抽象类型。这根是最容易被忘掉的,说一句「实现 XX 接口」它就会出现。
*--实线加实心菱形,菱形在整体那一侧。部分离开整体活不了:删掉 Order,它的 LineItem 跟着没。子对象没有独立身份时用它。
o--实线加空心菱形。同样是「有」,但部分能独立存在 —— 球队解散了球员还在。分不清用哪个时,问一句:这个子对象会被单独查询吗?
-->一根普通实线,可以加方向、加标签、加「1」「*」这样的基数。两个类只是彼此知道对方时的默认选择,领域模型里大部分线都是这种。
..>虚线加开放箭头。最弱的一种:一个类把另一个当参数、返回值或局部变量用,但不持有它。想说明控制器调了谁、又不想暗示所有权时用这个。
不需要。打开模板、手改 Mermaid 源码完全不用注册 —— 这两件事都在你的浏览器里完成。用对话改图才需要登录。
两条路,各管一类改动。对话管「结构性」的:「把这两个类合了」「Repository 改成接口」「Order 以下的全删掉」—— 说一轮重画一张。分屏编辑器管「精细」的:方法名打错了、关系标签换个词、成员顺序调一调。多数人的用法是:导入 → 在对话里把形状聊定 → 回编辑器抛光。
看得懂,因为模板是结构化数据,不是一张图片或者一坨文本。导入的类和关系直接成为这轮对话的工作状态,所以「删掉 Payment」删的就是那个类以及挂在它身上的所有关系 —— 助手不是在根据一段描述重新猜你的图。
类图描述的是代码:带行为的类型,有方法、有继承、有接口。ER 图描述的是存下来的数据:表、字段、键和基数,完全不涉及行为。你要画的东西有方法,那就是类图;它最终对应一次 schema 迁移,那就是 ER 图。
问一句部分能不能单独存在。删掉整体就必须删掉部分 —— 比如 Order 和它的 LineItem —— 那是组合,实心菱形。部分能独立活下来,比如球队解散后球员还在,那是聚合,空心菱形。实在拿不准,画一根普通关联比画错菱形诚实。
在类体里加 <<interface>> 构造型,然后用虚线实现箭头 <|.. 连实现类,比如 PaymentStrategy <|.. StripeStrategy。同一套写法还能用 <<abstract>>、<<enumeration>>,以及任何你们团队自己的构造型。这里有四个模板现成地用到了它。
SVG、PNG,以及 Mermaid 源码本身。SVG 放多大都不糊,画大型层次时有用;PNG 贴幻灯片和工单最省事;源码则可以跟代码一起提交,让图和别的东西一样走评审。
限制来自可读性,不是工具。超过十五个类左右,人就不跟着连线看了。按限界上下文或者按分层拆开,再从一篇父文档链过去 —— 几张各说一件事的图,胜过一张挂图。这里的模板刻意都压在这条线以内。