UML详细讲解
本文是搜集整理学习使用,信息来源:gd_沐辰 - 博客园 (cnblogs.com)
1.UML概述
1.1.什么是UML
统一建模语言(UML)是一种通用的可视化建模语言,可以用来描述、可视化、构造和文档化软件密集型系统的各种工件。
UML是独立于过程的,它适用于各种软件开发方法、软件生命周期的各个阶段、各种应用领域以及各种开发工具。
注:UML不是一种程序设计语言,其描述的模型可以和各种编程语言相联系。
1.2.UML的目标
- 为建模者提供可用的、富有表达力的、可视化的建模语言,以开发和交换有意义的模型。
- 提供可扩展性和特殊化机制以延伸核心概念。
- 支持独立于编程语言和开发过程的规范。
- 为理解建模语言提供正式的基础。
- 推动面向对象建模工具市场的成长。
- 支持更高级的开发概念。
1.3.UML的应用范围
1.4.UML的构造块:事物、关系、图
2.用例图
2.1.用例图基本概念
用例图是用来描述系统功能的技术,表示一个系统中用例与参与者及其关系的图,主要用于需求分析阶段。
用例图的基本组成元素:参与者、用例、元素之间的关系。
2.1.1.使用范围——需求分析
- 捕获需求。描述功能需求、行为需求(系统要完成什么任务)
- 分析需求。明确类和对象,建立之间的关系
2.1.2.基本概念
- 用例图是表示一个系统中用例与参与者关系之间的图。它描述了系统中相关的用户和系统对不同用户提供的功能和服务。
- 用例图相当于从用户的视角来描述和建模整个系统,分析系统的功能与行为。
- 用例图中的主要元素包括参与者、用例以及元素之间的关系。此外,用例图还可以包括注解和约束,也可以使用包将图中的元素组合成模块。
2.1.3.用例图示例
2.2.参与者
2.2.1.参与者概念
- 参与者是与系统主体交互的外部实体的类元,描述了一个或一组与系统产生交互的外部用户或外部事物。
- 参与者位于系统边界之外,而不是系统的一部分。
- 参与者是从现实世界中抽象出来的一种形式,却不一定确切对应的现实中的某个特定对象。
参与者的表示:
2.2.2.如何确认参与者
通过对参与者进行关注和分析,我们可以把重点放在如何与系统交互这一问题上,便于进一步确定系统的边界。另外,参与者也决定了系统需求的完整性。
确定参与者可以从以下几个角度来考虑:
- 为系统提供输入的人或事物
- 接收系统输出的人或事物
- 需要接入的第三方系统或设备
- 时间是否会触发某些事件
- 负责支持或维护系统中信息的人
2.2.3. 参与者分类
主要业务参与者:主要从用例的执行中获得好处的关联人员。
主要系统参与者:直接同系统交互以发起或触发业务或系统事件的关联人员。
外部服务参与者:响应来自用例的请求的关联人员。
外部接收参与者:从用例中接收某些价值或输出的非主要的关联人员。
2.2.4.参与者的泛化关系
当系统中的几个参与者既扮演自身的角色,同时也有更一般化的角色时,可以通过建立泛化关系来进行描述。
与类相似,父参与者可以是抽象的,即不能创建一个父参与者的直接实例,这就要求属于抽象父参与者的外部对象一定能够属于其子参与者之一。
2.3.用例
2.3.1.用例的概念
用例是类元提供的一个内聚的的功能单元,表明系统与一个或多个参与者之间信息交换的顺序,也表明了系统执行的动作。
简单来说,用例就是某一个参与者在系统中做某件事从开始到结束的一系列活动的集合,以及结束时应该返回的可观测、有意义的结果,其中也包含可能的各种分支情况。
用例与用例图被广泛使用于系统的需求建模阶段,并在系统的整个生命周期中被不断细化。
用例表示如下:
2.3.2.用例与参与者的关系
一个用例可以隶属一个或多个参与者,一个参与者也可以参与一个或多个用例。用例与参与者之间存在关联关系。
主参与者与次参与者:通常来说主参与者是用例的重要服务对象,而次参与者处于一种协作地位。
2.3.4.用例的特征
用例的特征保证用例能够正确地捕捉功能性需求,同时也是判断用例是否准确的依据。
- 用例是动宾短语
- 用例是相对独立的
- 用例是由参与者启动的
- 用例要有可观测的执行结果
- 一个用例是一个单元
2.4.用例之间的关系
用例之间的关系有:泛化关系、依赖关系(包含、扩展)
2.4.1.泛化关系
与参与者的泛化关系相似,用例的泛化关系将特化的用例与一般化的用例联系起来。子用例继承了父用例的属性、操作和行为序列,并且可以增加属于自己的附加属性和操作。父用例同样可以定义为抽象用例。
用例之间的泛化关系表示为一根实线三角箭头,箭头指向父用例一方。如下图:
2.4.2.依赖关系——包含
包含指的是一个用例(基用例)可以包含其他用例(包含用例)具有的行为,其中包含用例中定义的行为将被插入基用例定义的行为中。
包含的两个基本约束:
- 基用例可以看到包含用例,并需要依赖于包含用例的执行结果,但是它对包含用例的内部结构没有了解;
- 基用例一定会要求包含用例执行。
包含表示为一个虚线箭头附加上《include》的构造型,箭头从基用例指向包含用例。
2.4.3.依赖关系——扩展
扩展指的是一个用例(扩展用例)对另一个用例(基用例)行为的增强。
扩展使用一个附加了《enxtend》构造型的虚线箭头表示,箭头指向基用例。
注意:扩展与包含的箭头方向是相反的,这表明扩展取决于扩展用例而非基用例,扩展用例决定扩展的执行时机,基用例对此一无所知。
扩展用例的使用包括四个部分:
- 基用例:需要被扩展的用例,“注册”用例。
- 扩展用例:提供所添加的行为序列的用例。
- 扩展关系:使用虚线箭头表示,箭头指向基用例。
- 扩展点:基用例中的一个或多个位置,表示在该位置会根据某条件来决定是否要中断基用例的执行从而执行扩展用例中的片段。
2.4.4.包含、扩展的区别
根本区别,包含是无条件执行,扩展是有条件执行。图的起点不同,终点也不同。
特性 | include | extend |
作用 | 增强基用例的行为 | 增强基用例的行为 |
执行过程 | 包含用例一定会执行 | 扩展用例可能被执行 |
对基用例的要求 | 在没有包含用例的情况下,基用例可以是也可以不是良构的 | 在没有扩展用例的情况下,基用例一定是良构的 |
表示法 | 箭头指向包含用例 | 箭头指向基用例 |
基用例对增强行为的可见性 | 基用例可以看到包含用例,并决定包含用例的执行 | 基用例对扩展用例一无所知 |
基用例每执行一次,增强行为的执行次数 | 只执行一次 | 取决于条件(0到多次) |
2.5.用例描述与文档
2.5.1用例描述概述
一个完整的用例模型应该不仅仅包括用例图部分,还要有完整的用例描述部分。
一般的用例描述主要包括以下几部分内容:
- 用例名称:描述用例的意图或实现的目标,一般为动词或动宾短语。
- 用例编号:用例的唯一标识符,在其他位置可以使用该标识符来引用用例。
- 参与者:描述用例的参与者,包括主要参与者和其他参与者。
- 用例描述:对用例的一段简单的概括描述。
- 触发器:触发用例执行的一个事件。
- 前置条件:用例执行前系统状态的约束条件。
- 基本事件流(典型过程):用例的常规活动序列,包括参与者发起的动作与系统执行的响应活动。
- 扩展事件流(替代过程):记录如果典型过程出现异常或变化时的用例行为,即典型过程以外的其他活动步骤。
- 结论:描述用例何时结束。
- 后置条件:用例执行后系统状态的约束条件。
- 补充约束:用例实现时需要考虑的业务规则、实现约束等信息。
2.5.2.前置条件与后置条件
前置条件指的是用例执行前系统和参与者应处于的状态。前置条件是用例的入口限制,它便于我们在进行系统分析及设计的时候注意到,在何时何地才可以合法地触发这个事件。
后置条件是用例执行完毕后系统处于的状态。后置条件是对用例执行完毕后系统状况的总结,用来确保用户理解用例执行完毕后的结果,并非其他用例的触发器。
前置条件与后置条件分别是用例在开始和结束时的必要条件。
2.5.3.事件流
事件流是对用例在使用场景下的交互动作的抽象,应该包括用例何时以及怎样开始和结束,用例何时与参与者交互,该行为的基本流和可选择的流。
基本事件流:描述的是用例中最核心的事件流,是用例大部分时间所进行的场景。
扩展事件流:描述的是用例处理过程中的一些分支或异常情况。
2.5.4.补充约束
补充约束用来描述用例在系统功能之外的内容,例如非功能需求、业务规则等等。
数据需求:与该用例相关的一些数据项的说明。
业务规则:与业务相关的逻辑和操作规则。
非功能性需求:例如性能、支持的并发量等。
设计约束:是从多个角度对用例或系统的约定。
2.6.用例文档实践
用例名称 | 提交订单 |
用例编号 | UC002 |
参与者 | 会员 |
用例描述 | 该用例描述一个系统会员提交一份订单的行为 |
触发器 | 当订单被提交时,用例触发。 |
前置条件 | 提交订单的一方需要完成登录操作 |
后置条件 | 如果订单中的商品有库存,则发货;否则提示用户当前缺货 |
基本事件流 | 1 参与者将订单信息提交至系统。 2 系统验证用户信息及订单信息合法后作出响应。 3 对于订单中的每种产品,系统根据订单中的数量检查产品库存数量。 4 系统统计订单中产品的总价格。 5 系统从会员的系统账户余额中扣除相应金额。 6 系统生成并保存订单信息并将订单发送至分销中心。 7 系统生成订单确认页面并发送给会员。 |
扩展事件流 | A-2 如果订单信息非法,系统通知会员并提示重新提交订单。 A-3 如果订单中产品数量超过产品库存量,则提示会员库存不足,暂无法购买,取消订单同时终止用例。 A-5 如果会员账户余额不足,系统给出相应提示,取消订单并终止用例。 |
结论 | 当会员收到系统发送的订单确认页面或其他异常信息时,用例结束。 |
数据需求 | D-1 订单信息包括订单号、参与者的会员账户名、商品种类数量、商品种类名称以及每种商品的数量。 |
业务规则 | B-1 只有当订单中商品信息确认无误后才能要求会员进行支付。 |
2.7.用例图使用要点
- 构建结构良好的用例。用例图中应该只包含对系统而言必不可少的用例与相关的参与者。
- 用例的名称不应该简化到使读者误解其主要语义的程度。
- 摆放元素时应尽量减少连接线的交叉,以提供更好的可视化效果。
- 组织元素时应使在语义上接近的用例和参与者在图的位置上也同样接近,便于读者理解用例图。
- 可以使用注解或给元素添加颜色等方式突出图中相对重要的内容。
- 用例图中不应该有太多的关系种类。
2.8.用例图建模技术
2.8.1.对系统的语境建模
- 识别系统边界。
- 识别参与者。
- 如果需要,将具有相同特征的参与者使用泛化关系加以组织。
- 如果需要,对某些参与者应用一个构造型以便加深理解。
- 将参与者应用到用例图中,并描述参与者与用例间的通信路径。
2.8.2.对系统的需求建模
- 识别参与者。
- 对于某个参与者,考虑其期望系统提供的行为或与系统的交互。
- 将行为提炼成用例。
- 完善其他用例。分解用例中的公共行为与扩展行为,放入新的用例中以供其他用例使用。
- 创建用例图。
- 如果需要,在用例图中添加一些注解或约束来陈述系统的非功能需求。
2.9.案例——学生选课系统
某学校的网上选课系统主要包括如下功能:
管理员通过系统管理界面进入,建立本学期要开的各种课程,将课程信息保存在数据库中并可以对课程进行改动和删除。
学生通过客户机浏览器根据学号和密码进入选课界面,在这里学生可以进行三种操作:查询已选课程,选课以及付费。
同样,通过业务层。这些操作结果存入数据库中。
步骤:
- 确定系统边界
- 确定参与者(名词)
- 确定用例(动宾结构)
- 确定关系(联系)
参与者:学生、教务人员、数据库
用例:选课、查询、支付课时费用、登陆、修改课程、添加课程、删除课程
关系:关联关系、泛化关系
3.类图
3.1.类图简介
类图的定义:是显示一组类、接口、协作以及它们之间关系的图。
类图主要包含7种元素:类、接口、协作、依赖关系、泛化关系、实现关系、关联关系。
类图:包、子系统,用来把模型元素聚集成更大的组块。
类图:约束、注解
3.2.类
- 类是一组拥有相同的属性、操作、方法、关系和行为的对象地描述符。
- 类定义了一组有着状态与行为的对象。类的状态由属性和关联来描述,个体行为由操作来描述,对象的生命周期则由附加给类的状态机来描述。
- 在UML中,类表达成一个有三个分隔区的矩形。其中顶端显示类名,中间显示类的属性,尾端显示类的操作。
3.2.1.类——属性
可见性:描述了该属性在那些范围内可以被使用。
可见性 | 英文限定符 | UML标准图示 | Rose图示 | 说明 |
公有 | public | + | 其他类可以访问 | |
私有 | private | - | 只对本类可见,不能被其他类访问 | |
保护 | protected | # | 对本类及其派生类可见 |
类型:属性的数据类型,可以系统固有,也可以用户自定义。属性的类型决定了该属性的所有可能取值的集合。
3.2.2.类——操作
可见性:同样描述该操作在那些范围内可以使用,与属性的可见性相同。
参数列表:是一些按照顺序排列的属性定义了操作的输入。例如:oper(out arg1:int, arg2:double=3.2)
返回类型即回送调用对象消息的类型。void关键字表示无返回值。
特性是对操作性质的约束说明。
3.2.3.类——职责
职责是类的契约或责任。当创建一个类时,就声明了这个类的所有对象具有相同种类的状态和相同种类的行为。在较高的抽象层次上,这些相应的属性和操作正式要完成类的职责的特征。
类的职责是自由形式的文本,在非正式的类图中,可以将职责列在类图操作下的另一分割栏中。
3.3.接口
- 接口是一个被命名的操作集合,用于描述类或组件的一个服务。
- 接口不包含属性与方法实现,但可以有一些操作。接口的所有内容都是公有的。
- 接口代表了一份契约,实现该接口的类元必须履行它。
- 在UML中,接口由一个带名称的小圆圈表示;也可以表示为带有<<interface>>构造型的类
3.4.类图中的关系
UML中最常用的四种关系,即关联关系、泛化关系、依赖关系和实现关系。
3.4.1.类图中的关系——关联关系
- 关联的实例被称为链,每个链由一组有序或无序的对象组成。
- 关联关系靠近被关联元素的部分称为关联端,关联的大部分描述都包含在一组关联端的列表里,每个端用来描述关联中类的对象的参与
- 二元关联、自关联、N元关联。
注意要点
关联名称:放在关联路径的旁边,但远离关联端。
角色:放在靠近关联端的部分,表示该关联端连接的类在这一关联关系中担任的角色。角色名上也可使用可见性修饰符号。
多重性:放在靠近关联端的部分,表示在关联关系中源端的一个对象可以与目标类的多少个对象之间有关联。
导航性:一个布尔值,用来说明运行时刻是否可能穿越一个关联。
限定符:是二元关联上的属性组成的列表的插槽,其中的属性值用来从整个对象集合里选择一个唯一的关联对象或者关联对象的集合。
约束:关联间的约束关系。
现实例子
比如客户和订单,每个订单对应特定的客户,每个客户对应一些特定的订单;再例如公司和员工,每个公司对应一些特定的员工,每个员工对应一特定的公司。(表示有关联,也可以表示多重性)
派生关联:属于一种派生元素。它不增加语义信息,只是一种可以由两个或两个以上的基础关联推算出来的虚拟关联。
两种特殊的关联关系:聚合关系与组合关系
1.聚合关系:描述“整体-部分”的关联关系
聚合关系没有改变整体与部分之间整个关联的导航含义,也与整体和部分的生命周期无关。(部分与整体相互独立)
2.组合关系:描述“整体-部分”的关联关系
组合关系中的部分要完全依赖于整体。
关联与聚合的区别
- 关联关系所涉及的两个对象是处在同一个层次上的。比如人和自行车就是一种关联关系,而不是聚合关系,因为人不是由自行车组成的。聚合关系涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。比如:电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
- 对于具有聚集关系(尤其是强聚集关系)的两个对象,整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失,部分也就随之消失。比如张三的电脑被偷了,那么电脑的所有组件也不存在了,除非张三事先把一些电脑的组件(比如硬盘和内存)拆了下来。
聚合与组合的区别
聚合关系:涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。比如:电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
组合关系:代表整体的对象负责代表部分对象的生命周期。公司不存在,部门也没有意义了。再例如:人和五脏六腑、四肢的关系。
3.4.2.类图中的关系——泛化关系
泛化关系定义为一个较普通的元素与一个较特殊的元素之间的类元关系。其中描述一般的元素称为父,描述特殊的元素称为子。(子类是父类的继承,则父类就是子类的泛化。)
通过泛化对应的继承机制使子类共享父类的属性和操作,小了模型的规模,同时也防止了模型的更新所导致的定义不一致的意外。
泛化关系的特征:
- 传递性:一个类子类的子类同样继承了这个类的特性。在父方向上经过了一个或几个泛化的元素被称为祖先,在子方向上则被称为后代。
- 反对称性:泛化关系不能成环,即一个类不可能是自己的祖先和自己的后代。
泛化关系的两种情况
- 单继承:每个类之多能拥有一个父类。编程语言:C#、Java等
- 多重继承:子类可以有多个父类并继承了所有父类的结构、行为和约束。编程语言:C++等
3.4.3.类图中的关系——依赖关系
依赖关系表示的是两个元素之间语义上的连接关系。对于两个元素X和Y,如果元素X的变化会引起对另一个元素Y的变化,则称元素Y依赖于X。其中,X被称为提供者,Y被称为客户。
现实例子:
比如说你要去拧螺丝,你是不是要借助(也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作。
对于类图而言,主要有以下需要使用依赖的情况:
- 客户类向提供者类发送消息。
- 提供者类是客户类的属性类型。
- 提供者类是客户类操作的参数类型。
3.4.4.类图中的关系——实现关系
实现关系用来表示规格说明与实现之间的关系。在类图中,实现关系主要用于接口与实现该接口的类之间。
一个类可以实现多个接口,一个接口也可以被多个类实现。
实现关系的两种表示法:
- 当接口元素以带构造型的类的方式表示时,用虚线三角形箭头表示。
- 当接口元素以小圆圈方式表示时,用实线表示。
3.5.综合例子
更多推荐
所有评论(0)