如何画出规范的 UML 用例图
阿里妹导读
1.不会找用例:业务用例、系统用例又都是啥啊?我该如何把用例写对啊?😕
2.两个用例图分不清楚:业务用例图和系统用例图感觉好像啊,似乎没啥区别啊?🤔
一、如何识别正确的用例
这个世界的功能性体现在,首先有某人的一个愿望,这个愿望驱使人去做事并获得一个确定的结果。如果没有愿望,功能性就无从谈起。一个系统就是由各种各样的愿望组成的,换句话说,各种各样的人为着各自的目的做着各种各样的事情共同组成了一个系统。如果我们要描述一个系统的功能性需求,就要找到对这个系统有愿望的人,让他们来说明他们会在这个系统里做什么事,想要什么结果。如果所有对系统有愿望的人要做的所有事情都找全了,那这个系统的功能性就被确定下来了。
1.1 业务用例
试想一个餐馆如果不围绕“提供物美价廉的就餐服务”这一理念去经营,而是饭菜质量做的很差,提供了很多充电宝服务,那么这个餐馆的结果可想而知。
1.2 系统用例
说完业务用例我们再来看看系统用例,系统用例的定义是系统能够为执行者提供的、涉众可以接受的价值。其中的几个概念:
1.系统
封装了自身的数据和行为,能独立对外提供服务的东西才能称为系统。需要注意的系统是一个整体,系统可能会有很多子系统。比如银行转账交易时候需要做风控,如果有商家向银行售卖交易系统,那么风控这个子系统肯定是包含在整个交易系统内的,一起打包卖给银行的。
2.系统执行者
系统执行者的定义是在所研究系统外,与该系统发生功能性交互的其他系统。这里需要注意几点:
系统执行者一定是在系统外的,可以是人或者其他系统; 系统执行者必须是要和系统有交互的; 系统执行者不一定是业务执行者;
涉众是与要建设的业务系统相关的一切人和事,系统执行者也是涉众的一部分。
这里还是以餐馆为例,假如顾客是通过口头告诉服务员(不是自己扫码下单)我要点啥菜,服务员通过下单系统为顾客下单,那么研究这个下单系统可以得出:
1.系统执行者:服务员,虽然顾客作为餐馆这个组织的业务执行者,但是与下单系统直接交互的是服务员,所以服务员才是点餐系统的系统执行者;
2.涉众,这个就很多了,顾客、服务员、餐馆老板、厨师等等都是涉众,因为都是下单系统的利益关系者;
d.厨师担心下单系统分配不合理,所有的菜都分配给自己做;
一般这个下单系统可以登录、下单,查看下单记录,这些都是下单系统的一些功能。我们再来回顾下系统用例的概念:系统用例指的是系统能够为执行者提供的、涉众可以接受的价值。那我们接下来就从每个涉众的视角分析一下对这些功能的需要情况。
登录 | 下单 | 查看下单记录 | |
服务员 | 我需要,要不然别人下错单了怪我头上咋办 | I need it! | 我需要,方便查看顾客菜品上齐了没 |
顾客 | I don't care! | 能不能下单直接影响我能不能吃上饭 | 我也需要,得打印出来我的菜单,结账时候好核对 |
老板 | 我也需要,可以看看服务员的工作情况 | 下单系统不能下单我买它来干啥 | 我需要,方便订单管理,也方便看看哪个菜客人点的最多 |
厨师 | I don't care! | 不能下单谁告诉我该做什么菜 | 我需要,要不然说我少做了一道菜没法解释 |
所以,从上可以得出下单、查看下单记录满足系统用例的概念,系统用例图如下
可以看到,和业务用例不同的是在研究系统用例时我们需要把视角切换到系统,从系统出发看看能为执行者提供什么样的、涉众都可以接受价值。
Tips:
1.用例的名字一般是动宾结构,也就是“动词+名词”,但是不严格要求的。比如“成果分析”这个行业术语没必要硬倒过来改成“分析成果”
2.老老实实去研究业务流程,做好业务建模,尽量从业务序列图中映射出系统用例,这样得到的系统用例才是是最真实的。
3.用例是可以有主执行者和辅执行者的:主执行者从执行者指向用例,而辅执行者从用例指向执行者,主执行者发起用例的交互,辅执行者在交互过程中被动参与进来。一般说来,辅执行者是人肉系统的情况比较少,更多时候是另一个非人智能系统。
4.主执行者和辅执行者是相对于用例来说的,“ xx 是xx用例的主/辅执行者” 是正确的,“ xx 是xx系统的主/辅执行者” 说法是错误的。
二、如何区分业务用例图和系统用例图
相信经过上面的分析,你已经发现了两个用例图的异同点,如果没有,我再贴一下两个图(便于对比下单系统就简化成下单这个一个用例),便于更直观的对比:
没错,两个图的最大的不同就是有无“/”,业务用例图在业务执行者和业务用例上是有“/”的,系统用例图在系统执行者和系统用例图上没有“/”,就是这么简单。所以现在再看到下面这个几个图,你是不是可以一眼看出其中的问题了。
三、如何用 PlantUML 画出规范的用例图
PlantUML 是一个快速创建 UML 图形的组件或者可以说是语言,通过简单和直观的语言来定义图形。其在学习成本、效率、团队协同以及维护成本上都有比较大的优势,所以推荐使用 PlantUML 来画图。
用例图画起来其实很简单,主要就是四个要素,这里以系统用例为例,四个要素分别是系统、执行者、用例、关系。
3.1 系统
系统用一个矩形块表示,在 UML语法中是rectangle。如下:
@startuml
rectangle "xx 系统" {
}
@enduml
3.2 执行者
执行者是用火材人表示,在 UML 语法中是actor,主要有两种写法,如下:
@startuml
'系统执行者的两种写法'
actor Actor1
:Actor2:
'业务执行者的两种写法'
actor/ Actor3
:Actor4:/
@enduml
3.3 用例
用例是用一个椭圆表示。在UML 语法中是usecase ,业务用例和系统用例的两种写法如下:
usecase/ " 业务用例 1" as UC1
'业务用例的第二种写法:() + 用例名称 + /'
(业务用例 2)/ as UC3
usecase "系统用例 1" as UC2
'系统用例的第二种写法:() + 用例名称 '
(系统用例 2)
3.4 关系
系统用例图中关系主要有四种,分别是关联、包含、扩展、泛化。
3.4.1 关联
关联是执行者和用例之间的一种关系,一般用实线 + 实心箭头表示:
actor Actor
rectangle "xx系统" {
usecase "系统用例 1" as UC1
}
Actor -> UC1
你无法区分 Actor1 和 Actor2 谁是主执行者谁是辅执行者,又或者两个都是主执行者?加上箭头后就非常容易区分,如下
3.4.2 包含
包含是用例之间的一种关系,其中一个用例(称为基本用例)的行为包含了另一个用例(称为包含用例)的行为,用虚线箭头 + <<include>>表示,箭头指向包含用例。
包含关系意味着包含用例是基本用例中不可缺少的一个执行步骤,如果缺少了该包含用例,基本用例就会变得不完整,可类比类图中对象之间的组合关系。使用包含关系的两个场景:
当基本用例较复杂时,可以分解出一些包含用例; 当两个或以上的基本用例存在一些重复行为时,可以提炼出一个包含用例;
'加入下面代码指定方向,使 UML 从左往右更直观'
left to right direction
actor Actor
rectangle "xx系统" {
usecase "基本用例" as UC1
usecase "包含用例 1" as UC2
usecase "包含用例 2" as UC3
}
Actor --> UC1
UC1 ..> UC2 : <<include>>
UC1 ..> UC3 : <<include>>
上面我用了Actor --> UC1、UC1 ..> UC2,有兴趣的可以换成->、.>看看效果
3.4.3 扩展关系
扩展是用例之间的一种关系,其中一个用例(称为扩展用例)的行为增强了另一个用例(称为基本用例)的行为,用虚线箭头 + <<extend>>表示,箭头指向基本用例。
扩展用例是对基本用例的一种补充或强化,即使没有该扩展用例,对基本用例也不会产生直接影响,基本用例自身仍然是完整的。也就是说扩展用例是基本用例的一种可能的补充,如购买运费险就是对下单这一用例的扩展,买不买运费险都不影响下单。
left to right direction
actor Actor
rectangle "xx系统" {
usecase "基本用例" as UC1
usecase "扩展用例" as UC2
}
Actor --> UC1
UC1 <.. UC2 : <<extend>>
3.4.4 泛化
泛化关系也可以称作继承关系(类比类图中的泛化),用一个实线 + 空心箭头来表示,可以表示执行者间的关系也可以表示用例之间的关系。
left to right direction
actor Actor
rectangle "xx系统" {
usecase "支付" as UC1
usecase "微信支付" as UC2
usecase "支付宝支付" as UC3
}
Actor --> UC1
UC1 <|-- UC2
UC1 <|-- UC3
四、一个案例
这里我们以某银行的 App 为例,作为银行的一个系统我们对其进行分析:
1.系统:那自然是这个 App
2.系统执行者
a.主执行者:一般来银行办业务的客户都是主执行者,包括个人用户和企业用户;
3.系统用例:作为银行的线上业务,包含转账、查询余额、理财、贷款。
4.关系:这里需要注意的是转账过多有可能会超过限额,这个时候会提示超限;在办贷款业务之前,银行肯定会对用户的资产进行评估,这样才能决定其贷款额度。
@startuml
left to right direction
actor 客户 as Actor
actor 银行 as Actor2
rectangle "某银行App" {
usecase "转账" as UC1
usecase "查询余额" as UC2
usecase "理财" as UC3
usecase "贷款" as UC4
usecase "评估资产" as UC5
usecase "提示限额" as UC6
}
Actor <|-up- 个人用户
Actor <|-up- 企业用户
Actor --> UC1
Actor --> UC2
Actor --> UC3
Actor --> UC4
UC1 ----> Actor2
UC2 ----> Actor2
UC3 ----> Actor2
UC4 ----> Actor2
UC4 .left.> UC5 :<<include>>
UC1 <.down. UC6 :<<extend>>
@enduml
欢迎加入【阿里云开发者公众号】读者群
微信扫码关注该文公众号作者