UML用例建模解析(一)
【作者:刘伟 http://blog.youkuaiyun.com/lovelion】
UML是软件开发中绘制软件蓝图使用标准语言之建模技术,通过UML可以构造软件系统的需求模型(用例模型)、静态模型、动态模型和架构模型。UML是以图形和文字符号来描述一个系统,越来越多的软件企业在招聘中也需要应聘者具备一定的UML知识基础和实践经验。
很多人在尝试使用UML图形来构造一个软件系统的蓝图,然而在使用UML的过程中,有些人并没有深入理解这些图的真正涵義,以及这些图在绘制过程中的一些技巧。我将陆续在软件项目中如何合理使用UML来提高软件开发效率并规范软件开发流程。
在本文中我将结合库存管理系统来深入浅出地讲述UML建模中的第一个模型——需求模型的构造(*即用例模型),包括如何绘制用例图、如何编写简洁而又清晰的用例文档,最後統合怎样通过用例图和用例文档来构造一個软件系统的需求模型。
在UML中,需求模型(*用例模型),它主要被用來描述系统的功能性需求(*即软件要实现的功能),以库存管理系统而言,就要有登录、注册、入库、出库、查看库存报表、增加员工信息等功能。常规的用例建模一般包括两个组成部分:绘制用例图和编写用例文档。
1. 绘制用例图
用例图包含两个主要组成元素:执行者(Actor参与者或角色)和用例(Use Case案例)。在用例图中,执行者是以“小人”符号表示,用例則以“椭圆”符号表示之,最简单的用例图如下:
如上例用例图中,“仓库管理员”表示执行者,“入库”表示一个用例(*即代表系统某一个功能)。
执行者一般是指與系统直接作交互的事物,执行者主要可分為如下三类:
(1) 指直接使用系统的人:如使用一个库存管理系统的仓库管理员、仓储部经理等用户,其中仓库管理员可以通过系统作入库和出库等操作,仓储部经理則可通过系统查看各种报表,如库存报表、财务报表等;
(2) 与该系统相关的其他系统:如在库存管理系统中如果涉及到付款操作,則需要使用另一个软件——支付系统,此时支付系统就是库存管理另一执行者;
(3) 自动发生的事件:如时间、温度等自动事件,如果库存管理系统要求每晚零点执行一个数据汇总之操作,此时时间就成为该操作的执行者。
识别一个系统的执行者是用例建模的第一步,在识别出一个系统的执行者后,接著需要寻找系统可用的用例(*即功能需求)。用例一般是指执行者对系统一序列操作流程之統稱,如库存管理系统中,仓库管理员可以登录、入库、出库等操作,故在这里登录、入库、出库都是用例,它们都对应系统所提供的一个功能。以用例圖來体现执行者和软件系统的交互过程,因此只用简单的“椭圆”来表示用例太过简单,对于每一个用例,需要编写一个详细的用例文档,在下一节将介绍如何编写用例文档。
UML用例建模解析(二)
(1) 关联关系
关联关系(*通信关系)是指执行者可对某个用例进行操作之結合关系,如下图所示,“经理”對庫存系統具有一个“查看库存报表”功能,因此可以在执行者“经理”和用例“查看库存报表”之间建立一个关联关系,关联关系是以实线表示。
(2) 泛化关系
执行者本身之间可具有之关系只有一种即泛化关系,用带有空心三角形的实线表示之,如下图所示,仓库管理员、系统管理员、经理都是员工的一种,因此员工拥有的功能这三者都拥有,如登录、修改个人信息等,为了可减少用例个数并且使系统更加符合面向对象设计规范,可对执行者以泛化進行出所有人,将各类执行者都具有相同的功能移至父执行者,而将屬於每类执行者特有的功能保留在子执行者中。
至於常见用例本身之间的关系有两种:包含关系和扩展关系,下面介绍这两种关系的含义以及在用例图中如何表示:
(3) 包含关系
如果多个用例都具有一部分相同的行为,可以将这部分相同的行为作为一个单独用例予以抽取出来,再与原来的用例形成一个包含关系。如仓库管理员在进行入库、出库等操作之前需要先登录,故登录是入库、出库流程的基本组成部分,因此 “入库”和“出库”用例要包含 “登录”用例。在UML中,包含关系用依赖线(虚线)箭頭加上<<include>>標籤表示之,且箭頭要由原始用例指向包含用例,如下图所示:
(4) 扩展关系
扩展关系(*延伸关系),如果一个用例在执行时可能会使用到另一个用例,或者要使用一个新的用例对原有用例的行为进行扩展时,就可以使用扩展关系來表示,如仓库管理员在入库时发现某种商品在系统中暂不存在,则可以增加新的商品信息;如果入库商品均已存在,则无需增加商品信息,此时 “增加商品信息”用例可作为 “入库”用例的扩展用例。只要在需要扩展的原始用例中指定一个扩展点(*即需扩展的位置),在下一节编写用例文档中将学习如何设置扩展点。
在UML中,擴展关系用依赖线(虚线)箭頭加上<<extend>>文字標籤表示之,箭頭則由扩展用例指向原始用例,如下图所示:
包含关系和扩展关系箭头的指向可以口诀記憶:必含出另一用例(箭头向外);可扩進另一用例(箭头向內)。
其實用例本身之间还存在一种与执行者类似的泛化关系,但不太常见。
UML用例建模解析(三)
2. 编写用例文档
绘制用例图只是完成了用例建模最基本也是最简单的一步,用例建模的核心在于编写用例文档(*用例规约或用例描述)。顾名思义,用例文档是用于描述用例的文档,每一个用例必須对应于一个用例文档,在用例文档中則要用文字的方式描述用例的执行过程(即执行者与系统的交互过程)。
用例文档只要通俗易懂,不仅项目的开发人员能够理解,系统的用户以及客户也能够看懂用例文档。一个完整的用例文档包括用例编号、用例名、执行者、前置条件、后置条件、涉众利益、基本路径、扩展路径、字段列表、业务规则、非功能需求和设计约束等组成部分。
一般在系统中需要给所有的用例一个统一规范的编号,如库存管理系统,可以使用StockUC001、StockUC002等来对用例进行编号。每一个用例都需要提供一个清晰易懂的用例名,一般使用“动词+名词”的形式,如“查看库存报表”、“增加员工信息”、“增加商品信息”等,但对于一些俗语可以使用简稱來代表,如“登录”、“注册”、“入库”、“出库”等。
前置条件是用例执行之前所处的状态,它必须是软件系统可以识别到的状态,如用例“入库”的前置条件是“仓库管理员已成功登录”,而不能是“仓库管理员已打开电脑”,因为是否“打开电脑”库存管理系统不能识别到;后置条件是用例执行之后具备的状态,它也必须是系统能够识别到的,如用例“入库”的后置条件是“系统保存入库信息,更新相关商品的库存量”,而不能是“用户退出系统”,因为“用户退出系统”不是“入库”操作所达到的系统状态。
涉众利益是对用例执行过程和结果很关心但不直接操作用例的人,如仓库管理员在入库和出库时,虽然经理不直接入库,但是他们对这个过程和结果很关心,因此经理是涉众;如在火车站买票时,直接使用售票系统的是售票员,但是乘客很关心用例的执行结果,担心是否会弄错时间和车次,因此乘客是涉众。执行者是直接执行用例的人,他们通过用例直接执行系统所提供的功能。
路径(*即“流程”)是指执行者和系统交互的过程。在用例文档中最关键的部分是基本路径(*即“正常路径”或“开心路径”),它是用户最想看到、也最关心的路径,是用例建模中的核心。在路径中一般會包含若干步骤,这些步骤构成了一个完整的交互过程,在描述基本路径时,每一个步骤一般以执行者或者系统作为主语,如“仓库管理员输入待入库商品信息”,“系统验证该商品库存是否达到上限”等。在编写路径时需要注意以下几个问题:
(1) 需要对步骤进行编号,一般用阿拉伯数字1、2、3、…进行编号,表示步骤的先后次序。
(2) 不能出现专业术语,因为用例文档需要給系统的客户和用户都能够看懂,因此不能出现诸如“JDBC”、“SQL”这样的专业术语。
(3) 尽量使用主动语句,每一个步骤均以执行者或系统作为主语。
(4) 不要涉及到界面细节,如不能出现“仓库管理员在文本框中输入帐号”、“仓库管理员在密码框中输入密码”等句子,应该使用“仓库管理员输入帐号和密码”来代替。
(5) 如果出现大量数据输入或处理,需要将数据放入“字段列表”中,如系统管理员在增加员工信息时,會需要增加员工帐号、员工密码、员工所在部门、员工电话、员工邮箱等信息,可以在用例文档中使用“系统管理员输入员工信息”来代替,而对于“员工信息”的详细描述可以放在用例文档的“字段列表”中进行详细说明。
(6) 注意分支和循环的处理,在用例文档中,分支可放在接下来要介绍的扩展流程中;而循环可以直接放在步骤描述中,如在入库时可以一次入库多个商品的资料時,中间某些步骤說明如下:“2. 仓库管理员输入待入库商品信息;3. 系统验证该商品库存是否达到上限;4. 系统提示该商品入库信息增加成功;”,如果需要重复这几步,可以在基本路径中用如下语句描述:“如果还有商品需要入库,重复第2-4步”。
因基本路径是用例文档的核心,通过路径可以清楚了解执行者如何通过用例来实现相应的功能,因此,在编写用例文档时,需要认真细致编写基本路径,确保非专业人员都能够在读完基本路径后理解执行者和系统的交互过程。
除了基本路径之外,很多用例都存在一些替换路径和异常路径,通常可以将替换路径和异常路径统称为扩展路径。识别出一个用例的基本路径并不难,但是要找到所有的扩展路径是件很辛苦的工作。一个优秀的系统分析人员应该认真分析业务流程,试图寻找出在基本路径中每一个步骤可能存在的扩展方式以寻找出所有可能的扩展路径。如仓库管理员在入库时可能会发生一些异常情况,如“供应商不存在”、“待入库商品不存在”、“入库时商品超过库存上限”等,則需要使用扩展路径來对这些情况进行清晰的描述,如“供应商不存在”,则需要设置一个扩展点,先执行“增加供应商信息”用例,再选择供应商编号,在扩展流程中可以这样表示:“1a. 供应商不存在 1. 扩展点1:执行用例——StockUC003增加供应商信息;2. 仓库管理员选择供应商编号。”。在这里需要注意扩展路径的编号,如果是基本路径中步骤1的扩展路径,可以使用1a、1b、1c等方式表示,然后对于扩展出来的子路径再用1、2、3、…进行编号,其中在该子路径的第1步指明这是一个扩展点,该扩展点名为“扩展点1”,在此时需要执行另一个用例StockUC003“增加供应商信息”,则用例“入库”和用例“增加供应商信息”之间是扩展关系,“增加供应商信息”是对“入库”操作的扩展。如果没有扩展点则直接书写步骤就好,与基本路径步骤写法一致。
字段列表、业务规则、非功能需求和设计约束是对用例的补充描述,字段列表中包含某些步骤所涉及到的一些数据字段,如在“增加商品信息”用例中可以在其“字段列表”中详细列出商品信息的内容,如“商品信息包括:商品编号,商品名称,商品型号,商品类别,商品单价,商品数量,库存上限,库存下限”,“字段列表”为后续的数据库设计工作提供了极大的帮助;业务规则用于描述在步骤中执行者或系统在执行某些操作时需要满足的条件,如在“增加商品信息”用例中,其“业务规则”包括“商品编号不能为空,商品数量必须是大于等于0的整数,库存下限必须低于库存上限”等;非功能需求用于描述用例在可靠性、安全性、可用性、移植性等方面的一些要求,如“系统响应时间不能超过30秒”、“可以支持同时100个用户在线访问”等;设计约束是指设计过程中存在的一些待解决的问题,如“商品编号的编码问题”、“如何快速输入商品编号”等。
在实际软件开发过程中,用例编号、用例名、执行者、前置条件、后置条件和基本路径是一个用例必不可少的组成部分,其他部分可根据实际情况确定,可有可无。下面提供库存管理系统中“入库”用例的用例文档供参考:
用例名称 | 入库 |
用例编号 | StockUC006 |
执行者 | 仓库管理员 |
涉众利益 | 经理:了解各种商品的库存信息和每次入库信息。 系统管理员:了解入库操作是否能够正常执行,系统是否正确记录入库信息并更新商品库存。 |
前置条件 | 仓库管理员已成功登录。 |
后置条件 | 系统保存入库信息,更新相关商品的库存量。 |
基本路径 | 1. 仓库管理员选择供应商编号; 2. 仓库管理员输入入库商品信息; 3. 系统验证该商品库存是否达到上限; 4. 系统提示该商品入库信息增加成功; 如果还有商品需要入库,重复第2-4步 5. 仓库管理员提交入库信息; 6. 系统提示入库成功。 |
扩展路径 | 1a. 供应商不存在 1. 扩展点1:执行用例——StockUC003增加供应商信息; 2. 仓库管理员选择供应商编号。 2a. 待入库商品不存在 1. 扩展点2:执行用例——StockUC005增加商品信息; 2. 仓库管理员输入入库商品信息。 4a. 增加失败 1. 系统提示商品增加失败,超过库存上限; 2. 仓库管理员重新输入商品数量; 3. 系统再次验证该商品库存是否达到上限,直至该商品入库信息增加成功。 |
字段列表 | 入库商品信息包括:商品编号、入库数量、商品折扣。 |
业务规则 | 供应商编号不能为空; 商品编号不能为空; 入库数量必须为正整数,且不能为空; 商品折扣为0-1之间的小数(可包含0和1),且不能为空。 |
非功能需求 | 系统响应时间不能超过30秒。 |
设计约束 | 如何快速输入商品编号? |
总之,用例建模包括用例图的绘制和用例文档的编写,重要核心在于编写用例文档。用例建模是软件需求分析到最终实现的第一步,它是从用户的角度来描述软件系统的功能,描述人们如何使用软件系统。构造意义明确、格式规范的用例模型是软件成功的第一步,希望大家在每个软件项目的开发过程中都能够认真、细致地进行用例建模,为顺利完成项目开发任务奠定坚实的基础。