用例图栏目 ·

用例图泛化(Generalization)怎么画:角色继承/用例继承的正确方向

讲清用例图里的泛化(Generalization)是什么、箭头方向怎么判定,以及 Actor 泛化与用例泛化各自适用场景与常见误区。

在 UML 用例图里,“泛化(Generalization)”经常被画错:要么箭头方向反了,要么把本该用 «include» / «extend» / 普通关联表达的关系,硬塞成“继承”。

这篇按两个问题讲清楚:

  1. 箭头到底指向谁?(判断规则)
  2. Actor 泛化用例泛化分别什么时候用?(场景 + 反例)

如果你想直接把文字需求快速生成一张可编辑的用例图,可以用这个页面生成草稿后再微调:

1. 泛化是什么:一句话定义

用例图里的泛化表示 “更具体的是一种更一般的”(is-a / kind-of)。

  • 子(更具体)继承父(更一般)的语义
  • 子可以在父的基础上增加差异点

在用例图中,泛化通常出现在两处:

  • 参与者(Actor)泛化:某类角色是另一类角色的特化
  • 用例(Use Case)泛化:某个用例是另一个用例的特化

2. 箭头方向怎么判定(最常用、最不容易错的规则)

UML 泛化的记号是 空心三角箭头

规则:空心三角箭头永远指向“更一般(父类)”。

换句话说:

  • 你如果能读成“X 是一种 Y”,那箭头从 X 指向 Y

2.1 用一句“替换测试”快速判断

把你图上的两个元素(Actor 或用例)拿出来,套进这句话:

“A 是一种 B”

如果成立:

  • A 是子(更具体)
  • B 是父(更一般)
  • 箭头:A → B(空心三角指向 B)

例子(Actor):

  • “管理员是一种用户” ✅
  • 所以:管理员 → 用户(空心三角指向“用户”)

例子(用例):

  • “企业微信登录是一种登录” ✅
  • 所以:企业微信登录 → 登录(空心三角指向“登录”)

2.2 常见错误:把箭头当成“调用方向”

泛化不是流程、不是依赖、也不是“谁触发谁”。

如果你画箭头是为了表达:

  • “这个用例会执行那个用例”
  • “这个步骤里会复用那个步骤”

那你要找的往往是:

  • «include»(必做的复用)
  • «extend»(可选/条件触发的扩展)

3. Actor 泛化:什么时候用

Actor 泛化适合表达:不同角色具备同一组基础能力,但在此基础上存在额外权限或额外交互

3.1 典型场景:权限分层

假设系统里有两个角色:

  • 用户:能“浏览内容”“下单”
  • 管理员:除了用户的能力,还能“审核订单”“配置商品”

你可以这样画:

  • 管理员 → 用户(管理员是用户的一种)

好处是:

  • 用例图更干净:基础用例只连“用户”,管理员自动“继承”这些交互
  • 权限层级更直观

3.2 典型场景:渠道/终端差异

例如:

  • 客服(总称)
    • 在线客服
    • 电话客服

它们都能“查询订单”,但在“联系用户”的方式上不同。

这类“同类角色的特化”用 Actor 泛化很自然。

3.3 反例:把“组织关系”画成泛化

例如:

  • “财务部”
  • “公司”

这不是 is-a(“财务部是一种公司”不成立),而是组成关系/隶属关系。用例图里通常不表达组织结构;如果必须表达,也更适合在其他图里呈现(组织结构图、领域模型等)。

4. 用例泛化:什么时候用(更谨慎)

用例泛化比 Actor 泛化更容易被滥用。

它适合这种情况:

  • 父用例描述“目标不变、约束更抽象”的共性
  • 子用例描述“实现该目标的不同变体”

4.1 典型场景:同一目标的多个变体

例子:登录

  • 登录(抽象/通用)
    • 手机号验证码登录
    • 账号密码登录
    • 企业微信登录

画法:

  • 手机号验证码登录 → 登录
  • 账号密码登录 → 登录
  • 企业微信登录 → 登录

这里“登录”的用户目标一致:进入系统并建立会话;差别在认证方式。

4.2 典型场景:不同渠道的同一用例

比如“提交报销”在 Web 和移动端表现不同,但目标一致。

  • 提交报销
    • Web 端提交报销
    • 移动端提交报销

如果差异大到你不想写在同一个用例说明里,用例泛化可以帮助分层。

4.3 反例:把“可选步骤”画成用例泛化

例如“下单”过程中,有时会“使用优惠券”。

很多人会画:

  • 使用优惠券 → 下单(想表达“这是下单的一种”)

但“使用优惠券”不是“下单的一种”,它更像是下单过程中的可选子功能

这类更合适:

  • «extend»:使用优惠券 —«extend»→ 下单(在满足条件时扩展)

  • «include»:如果“使用优惠券”是每次下单必经步骤(通常不是),才用 include。

5. 一个简单的选择清单:泛化 vs include/extend

拿不准时,用下面的清单快速做决定。

5.1 你要表达的是“类型关系”吗?

问自己两句:

  • “A 是一种 B”是否成立?
  • A 是否能替代 B 出现在相同位置?

都成立 → 倾向用 泛化

5.2 你要表达的是“行为复用/条件扩展”吗?

如果你真实意图是:

  • 复用共同步骤(必做) → «include»
  • 条件触发的附加行为(可选) → «extend»

这两个比“用例泛化”更常用,也更不容易误导阅读者。

6. 画图时的落地建议(避免读者误解)

  1. 父元素命名要“更一般”

    • Actor 父类用“用户/员工/客户”等通用称呼
    • 用例父类用“登录/支付/提交申请”等目标级动词短语
  2. 不要用泛化表达流程

    • 用例图不擅长讲步骤顺序,步骤用活动图/时序图或用例说明写清楚
  3. 用例泛化别用太多层

    • 一层通常够了;层级过深会让图变“类图化”,可读性下降
  4. 对外沟通时,优先让图“能被读懂”

    • 如果团队对用例泛化理解不一致,宁可拆成多个独立用例 + 文字说明,也别强行用继承。

如果你希望我根据你的业务描述,顺手给出一版“Actor/用例/关系”的初稿(可直接导出编辑),可以把需求贴进去生成器再补充两三句约束:

写完草稿后,建议你检查两件事:

  • 空心三角是否都指向更一般的元素
  • 每一条泛化关系是否都能用“X 是一种 Y”读通