目录
一、UML及其建模工具
1. 模型及其作用
建模是为了更好地理解正在开发的系统:
- 模型帮助我们按照实际情况或按照我们所需要的样式将系统可视化
- 模型允许我们详细说明系统的结构或行为
- 模型给出了一个指导我们构造系统的模板
- 模型对我们作出的决策进行文档化
- 在构建物理实体之前先测试
- 与客户交流
- 降低复杂度
软件系统用对象(类)作为其构造单元(块):
- 要从问题空间或解空间的词汇中找出对象
- 类是对具有共同性质的一组对象的描述
- 不用太早进入代码的细节
- 每一个对象都有标识、状态和行为
2. UML介绍
UML定义:UML 是一种对软件系统的制作过程/产出物进行下述工作的描述语言,这些工作包括:可视化(visualizing)、详述 (specifying)、构造 (constructing)、文档化(documenting)
- UML 是可视化语言——UML 是图形化语言,便于交流
- UML 是一种可以详细描述的语言——所建的模型是精确的,无歧义和完整的
- UML 是用于构造系统或理解系统的语言——UML 既支持正向工程,又支持反向工程
- UML 是文档化语言——将所构造的系统记录下来,便于后续人员跟进
UML的构成:视图、图、模型元素和通用机制
视图:视图是表达系统某一方面特征的 UML 建模元素的子集,它是由一个或者多个图组成的对系统某个角度的抽象
用例视图:
用途:描述系统应该具备的功能,即被称为参与者(执行者)的外部用户所能观察到的功能
用例视图是几个视图的核心,它的内容直接驱动其他视图的开发
包含UML图:用例图
逻辑视图:
用途:描述用例视图中提出的系统功能的实现
逻辑视图既描述系统的静态结构,也描述系统内部的动态协作关系
包含UML图:类图、对象图、状态图、时序图、协作图、活动图
静态结构在类图和对象图中描述
动态模型在状态图、时序图、协作图、活动图中描述
使用者:分析人员、设计人员、开发人员
进程视图:
用途:考虑资源的有效利用、代码的并行执行以及系统环境中异步事件的处理
解决在并发系统中存在的通信和同步问题
包含UML图:状态图、协作图、组件图、活动图
使用者:开发人员、系统集成人员
图之间的关系
模型元素
事物(things)
- 结构事物(structural things)
- 行为事物(behavioral things)
- 分组事物(grouping things)
- 注释事物(annotational things)
UML 中的关系(relationships)
- 关联(association)
- 依赖(dependency)
- 泛化(generalization)
- 实现(realization)
- 聚合(polymerization)
结构事物:
UML 模型中最基本的结构化事物,包括类、接口、协作、用例、活动类、组件、节点
名称 | 属性 | 图片 |
类 | 对具有相同属性、方法、关系和语义的对象的抽象 | ![]() |
接口 | 类或组件提供特定服务的一组操作的集合,描述了类或组件的对外可见的动作 | ![]() |
协作 | 定义了交互操作,代表构成系统的模式的实现 | ![]() |
用例 | 描述系统对一个特定角色执行的一系列动作,组织动作事物 | ![]() |
活动类(对象) | 类对象有一个或多个进程或线程的类 | ![]() |
组件 | 实现了物理上可替换的系统部分 | ![]() |
节点 | 在运行时存在的一个物理元素,代表一个可计算的资源。通常占用一些内存和具有处理能力 | ![]() |
行为事物:
交互
一组对象在特定上下文中,为达到某种特定的目的而进行的一系列消息交换组成的动作
状态机
由一系列对象的状态组成
分组事物:
UML 模型中组织的部分
分组事物只有一种:包
包是一种将有组织的元素分组的机制
包只存在于开发阶段
注释事物:
UML 模型的解释部分
UML中的关系
关系 | 图 |
关联 | ![]() |
依赖 | ![]() |
泛化 | ![]() |
实现 | ![]() |
聚合/组合 | ![]() |
二、用例图
1. 用例图简介
用例图应用在软件开发的需求分析阶段,他描述了系统的功能以及如何使用一个系统
用例图显示谁将是相关的用户、用户希望系统提供什么服务以及用户需要为系统提供的服务
用例图最常用来描述系统以及子系统
用例图分为业务用例图和系统用例图
业务用例图:
2. 用例图的组成
用例图主要包含以下 6 个元素
- 参与者(Actor)
- 用例(Use Case)
- 关联关系(Association)
- 包含关系(Include)
- 扩展关系(Extend)
- 泛化关系(Generalization)
3. 参与者、用例与事件流
参与者的概念:是系统外部的一个实体,参与用例的执行过程。参与者由参与用例时所担当的角色来表示。每个参与者可以参与一个或多个用例
对参与者建模:
- 参与者对系统而言总是外部的
- 参与者可以直接或间接地同系统交互或使用系统提供的服务以完成某件事务
- 参与者表示人和事物与系统发生交互时所扮演的角色,而不是特定的人或特定的事物
- 一个人或事物在与系统发生交互时,可以扮演多个角色
启动者和支持者:启动者是用例的主要服务对象、另一类是扮演支持者角色的参与者
参与者间的关系:参与者之间可以具有泛化关系。在用例图中,使用泛化关系来描述多个参与者之间的公共行为
用例
- 外部可见的系统功能单元
- 在不揭示系统内部构造的前提下定义连贯的行为
- 不是需求或功能的规格说明
用例的表示:简单名(Simple Name)、路径名(Path Name)
识别用例:识别用例最好的方法就是从分析系统的参与者开始,考虑每个参与者是如何使用系统的
事件流
用例分析处于系统的需求分析阶段,这个阶段应该尽量避免考虑系统的细节问题,但是要实际建立系统,则需要更加具体的细节,这些细节写在用例对应的事件流文件中。
事件流的描述是独立于实现方法的,事件流描述系统“做什么”,而不是“怎么做”
事件流文件的组成
- 简要说明——与用例相关的说明,描述该用例的作用、应包括执行用例的参与者和通过这个用例要达到的结果
- 前提条件——用例执行前必须满足的条件,如另一用例必须要先执行
- 后置条件——用例执行完后必须要做的事情,如必须执行另一个用例
- 事件流程(主事件流、其他事件流、错误流 )——从用户角度描述执行用例的具体步骤,包括用例的开始和结束、用例如何与参与者交互、用例的正常流程、主事件流的变体以及错误流
描述方法——表格
4. 用例间的关系
关系 | 属性 | 图 |
关联关系(Association) | 表示参与者与用例之间的关系,不同的参与者可以访问相同的用例 | ![]() |
包含关系(include) | 一个用例可以简单地包含其他用例具有的行为,并把它所包含的行为作为自身行为的一部分,这称作用例间的包含关系。包含关系把几个用例的公共部分分离成一个单独的被包含用例,被包含用例称为提供者用例,包含用例称为客户用例。 如果两个以上的用例有大量一致的功能,则可以将这个功能分解到另一个用例中,其他用例可以和这个用例建立包含关系;一个用例的功能太多时,可以用包含关系建模成两个以上的用例,降低用例的复杂度 | ![]() |
扩展关系(extend) | 扩展用例被定义为基础用例的增量扩展 扩展关系是把新的行为加入到已有的用例中去 基础用例提供扩展点以添加新的行为 扩展用例插入到基础用例的扩展点上 扩展关系的特点:没有基础用例,扩展用例也是完整的用例 基础用例被执行时,一般不会涉及扩展用例,只有特定的条件发生,扩展用例才可能被执行,这是与包含关系的差别 | ![]() |
泛化关系(Generalization) | 泛化关系是一般和特殊的关系 一个用例(父用例)可以被特别地列举为一个或多个子用例 子用例表示父用例的特殊形式 子用例从父用例处继承行为和属性,还可以添加行为或覆盖、改变继承的行为 如果系统中一个或多个用例是某一个一般用例的特殊化用例时,就应该使用用例的泛化关系,例如: | ![]() |
5. 边界
边界——研究对象
6. 用例的粒度与层次
步骤 ≠ 用例
例:对于“哈工大教务处管理系统”,“登录”不算用例。对于一个身份识别系统(如:哈工大统一身份认证系统),“登录”就是一个用例
粒度:
层次:
(错误的层次示例,把研究对象(边界)由“医院管理系统”偷换成了“医院”)
三、活动图
1. 活动图
活动图是UML用于对系统的动态行为建模的另一种常用工具。它描述活动的顺序,展现从一个活动到另一个活动的控制流。活动图在本质上是一种流程图;活动图着重表现从一个活动到另一个活动的控制流
2. 活动图元素
动作状态
- 动作状态是指原子的,不可中断的动作,并在此动作完成后通过完成转换转向另一个状态
- 在UML中的动作状态图用平滑的圆角矩形表示
- 动作状态是原子的,无法分解为更小的部分
- 动作状态是不可中断的,一旦开始运行就不能中断,一直运行到结束
- 动作状态是瞬时的行为,它所占用的处理时间极短,有时甚至可以忽略
- 动作状态可以有入转换,入转换可以是动作流,也可以是对象流;动作状态至少有一条出转换,这条转换以内部的完成为起点,与外部事件无关
- 动作状态与状态图中的状态不同,它不能有入口动作和出口动作,更不能有内部转移
活动状态
- 活动状态用于表达状态机中的非原子的运行
- 在UML中活动状态和动作状态的图标相同,但活动状态可以在图标中给出入口动作和出口动作等信息
- 活动状态可以分解成其他子活动或者动作状态
- 活动状态的内部活动可以用另一个活动图来表示
- 和动作状态不同,活动状态可以有入口动作和出口动作,也可以有内部转移
- 动作状态是活动状态的一个特例,如果某个活动状态只包括一个动作,那么它就是一个动作状态
开始点
结束点——标志整个活动的结束或子流程的结束
子活动状态
分支与合并——分支一入多出、合并多入一出
分叉与汇合——分叉用将控制流分为两个或者多个并发运行的分支,汇合用于同步这些并发分支,以达到共同完成一项事务的目的
对象流
可以把对象放置在活动图中并用一个依赖将其连接到进行创建、修改或撤销等动作状态或者活动状态上,对象的这种使用方法就构成了对象流。对象流是动作状态或者活动状态与对象之间的依赖关系,表示动作使用对象或动作对对象的影响
3. 活动图与状态图的区别
活动图着重表现从一个活动到另一个活动的控制流,是内部处理驱动的流程
状态图着重描述从一个状态到另一个状态的流程,主要有外部事件的参与
四、类图/对象图
1. 类图的概念
描述类、接口及它们之间关系的图。显示系统中各个类的静态结构
2. 类图的元素
- 类(Class)
- 接口(Interface)
- 依赖关系(Dependency)
- 泛化关系(Generalization)
- 关联关系(Association)
- 实现关系(Realization)
3. 类
类是面向对象系统组织结构的核心,是对一组具有相同属性、操作、关系和语义的对象的抽象,包括名称部分(Name)、属性部分(Attribute)和操作部分(Operation)
名称:一个名词,分为简单名称和路径名称。每个单词首字母大写
属性:描述了类在软件系统中代表的事物(即对象)所具备的特性,类可以有任意数目的属性,也可以没有属性。在 UML 中,类属性的语法为[可见性] 属性名 [类型] [=初始值]
属性的可见性
- 公有(Public) “+” 所有类可见
- 私有(Private)“-” 该类及子孙可见
- 受保护(Protected)“#” 只对该类本身可见
- 包(Package) “~” 只对同一包声明的类可见
属性名——每个属性必须有一个名字以区别于类中的其他属性 ,属性名由描述所属类的特性的名词或名词短语组成。除了第一个单词外其余单词的首字母要大写
属性的初始值——保护系统的完整性,防止漏掉取值或被非法的值破坏系统的完整性
为用户提供易用性
操作——对类的对象所能做的事务的抽象,一个类可以有任意数量的操作或者根本没有操作。返回类型、名称和参数一起被称为操作签名。在 UML 中,类操作的语法为[可见性] 操作名 [(参数列表)] [:返回类型]
操作的可见性
- 公有(Public) “+”
- 私有(Private) “-”
- 受保护(Protected) “#”
- 包(Package) “~”
操作名——用来描述所属类的行为的动词或动词短语,命名规则与属性相同
操作的参数表 ——一些按顺序排列的属性定义了操作的输入。是可选的,即操作不一定必须有参数才行。定义方式:“名称:类型”,若存在多个参数,将各个参数用逗号隔开。参数可以具有默认值
操作的返回类型——是可选的,即操作不一定必须有返回类型。绝大部分编程语言只支持一个返回值。具体的编程语言一般要加一个关键字 void 来表示无返回值
4. 接口
在没有给出对象的实现和状态的情况下对对象行为的描述
包含操作但不包含属性
没有对外界可见的关联
一个类可以实现一个或多个接口
5. 类之间的关系
依赖关系——表示两个或多个模型元素之间语义上的关系。
客户以某种形式依赖于提供者
依赖关系的分类
- 使用依赖(Usage)
- 抽象依赖(Abstraction)
- 授权依赖(Permission)
- 绑定依赖(Binding)
使用依赖——表示客户使用提供者提供的服务以实现它的行为。使用(《use》)
使用依赖具体包括
- 调用(《call》):声明一个类调用其他类的操作的方法
- 参数(《parameter》):声明一个操作和它的参数之间的关系
- 发送(《send》):声明信号发送者和信号接收者之间的关系
- 实例化(《instantiate》):声明用一个类的方法创建了另一个类的实例
抽象依赖——表示客户与提供者之间的关系,依赖于在不同抽象层次上的事物,包括
- 跟踪(《trace》)
- 精化(《refine》)
- 派生(《derive》)
授权依赖——表达一个事物访问另一个事物的能力,包括
- 访问(《access》):允许一个包访问另一个包的内容
- 导入(《import》):允许一个包访问另一个包的内容并为被访问包的组成部分增加别名
- 友元(《friend》):允许一个元素访问另一个元素,不管被访问的元素是否具有可见性
绑定依赖——较高级的依赖类型,用于绑定模板以创建新的模型元素,包括
- 绑定(《bind》)
泛化关系——存在于一般元素和特殊元素间的分类关系,可以用于类、用例以及其他模型元素。描述了一种“is a kind of” 的关系
关联关系——一种结构关系,指明事物的对象之间的联系
关联关系包括
- 名称(Name)
- 角色(Role)
- 多重性(Multiplicity)
- 聚合关系(Aggregation)
- 组合关系(Composition)
- 导航性(Navigation)
关联的名称
- 使用一个动词或动词短语来命名关联
- 清晰而简洁地说明对象间关系
- 关联的名称并不是必需的
- 可以前缀或后缀一个指引阅读方向的方向指示符,以消除歧义
关联的角色
- 关联关系中一个类对另一个类所表现出来的职责
- 角色的名称应该是名词或名词短语,以解释对象是如何参与关系的
关联的多重性
- 指有多少对象可以参与该关联
- 可以表达一个取值范围、特定值、无限定的范围或一组离散值
- 格式:“min .. max” (均为int型)
- 赋给一个端点的多重性表示该端点可以有多少个对象与另一个端点的一个对象关联
聚合关系——一种特殊类型的关联,表示整体与部分关系的关联。描述了“has a”的关系
组合关系——组合是聚合关系中的一种特殊情况,是更强形式的聚合,又称强聚合。成员对象的生命周期取决于聚合的生命周期。聚合不仅控制着成员对象的行为,而且控制着成员对象的创建和析构
实现关系
- 规格说明(接口)和其实现之间的关系
- 客户必须至少支持提供者的所有操作
- 泛化和实现都可以将一般描述与具体描述联系起来
- 泛化将同一语义层上的元素连接起来,并且通常在同一模型内
- 实现将不同语义层内的元素连接起来,并且通常建立在不同的模型内
五、时序图/协作图
1. 交互图简介
交互图是描述系统中对象之间通过消息通信的图,在UML1.5中交互图包括:
- 序列图(也称时序图、顺序图)
- 协作图(也称通信图)
2. 时序图简介
序列图(时序图)用来描述系统中对象间通过消息进行交互,它强调消息在时间轴上的先后顺序
- 纵轴是时间轴,时间沿竖线向下延伸
- 横轴代表了在交互中的各独立的对象
用例图 | 类图 | 序列图 |
动态行为 (系统外在行为) | 静态结构 (系统内在结构) | 动态行为 (系统内在行为) |
参与者、用例 | 类 | 对象 |
包含、扩展、泛化 | 依赖、关联、泛化 | 消息 |
用例描述 | 事务模式 | BCE模式 |
业务流程 | 领域概念 | 概念与流程的关联 |
序列图主要包含 4 个元素:对象、生命线、消息、激活
对象
- 将对象置于序列图顶部意味着在交互开始的时候对象就已经存在了
- 如果对象位置不在顶部,那么表示对象是在交互的过程中被创建的
对象的名称——类名
创建对象
注销对象
如果要注销一个对象,只要在其生命线终止点放置一个 “X” 符号即可,该点通常是对删除或取消消息的回应
生命线
- 生命线是一条垂直的虚线,表示序列图中的对象在一段时间内的存在;每个对象底部中心的位置都带有生命线
- 生命线是一个时间线,从序列图的顶部一直延伸到底部,所用的时间取决于交互持续的时间
消息
- 消息定义的是对象之间某种形式的通信,它可以激发某个操作、唤起信号或导致目标对象创建或撤销
- 消息是两个对象之间的单路通信,从发送方到接收方的控制信息流
- 消息可以是信号,也可以是调用
- 消息可以用于在对象间传递参数
- 消息的编号:顺序编号,从1开始
- 在 UML 中,消息使用箭头来表示,箭头的类型表示了消息的类型
调用(call)
- 这是最常用的一种消息,它表示调用某个对象的一个操作(通常格式为“对象名.成员方法”)
- 可以是对象之间的调用,也可以是对象本身的调用
返回(return)
- 返回表示被调用的对象向调用者返回一个值
- 在序列图中,采用虚线箭头线来表示
发送(Send)
- 发送是指向对象发送一个信号
- 信号和调用不同,它是一种事件,用来表示各对象间进行通信的异步激发机制
- 调用是同步的机制,而信号是一种异步的机制
创建(Create)和注销(Destroy)
- 也就是创建和销毁一个对象
- 创建对象通常是利用构造方法来实现的,对象一创建,生命线就开始
- 生命终止符号用一个较大的叉形符号表示
激活
- 激活(Activation)表示该对象被占用以完成某个任务
- 去激活(Deactivation)指的则是对象处于空闲状态、在等待消息
- 在 UML 的序列图中,为了表示对象是激活的,可以将该对象的生命线拓宽成为矩形
- 其中的矩形称为激活条或控制期,对象就是在激活条的顶部被激活的,对象在完成自己的工作后被去激活
3. BCE模式
BCE模式(Ivar Jacobson发明的)又称Robustness分析法,是在系统分析阶段采用的分析模式
B:Boundary
C:Control
E:Entity
边界类——边界类用来隔离系统内部和外部,负责接收参与者的消息
控制类——控制类对应用例,用来控制用例执行期间的复杂运算或者业务逻辑。在分析阶段,通常针对一个用例生成一个控制类
实体类——对应于类图中领域概念中的类,封装了数据结构和数据存储有关的类
BCE四项原则
- 针对每一个用例,可以对应生成一个控制类
- 参与者对象只能跟边界对象互动
- 实体对象不能发送消息给边界对象和控制对象
- 特别情况,如只是对数据进行增加、删除、修改和查询操作也可以不设置控制对象,让边界对象直接发送消息给实体对象,以提高执行速度
4. 组合片段
在序列图中,为了表示分支和循环这两种行为,引入了交互片段、区域和操作符的概念。一个交互片段可以包含多个区域,每个区域拥有一个监护条件和一个复合语句
操作符——每个交互片段都有一个操作符,操作符决定了交互片段的执行方式
- opt——包含一个可能发生或可能不发生的序列,可以在临界条件中指定序列发生的条
- alt——可以在每个片段中设置一个临界条件来指示该片段可以运行的条件。else 的指示其他任何临界条件都不为true时应运行的片段,如果所有临界条件都为false并且没有else,则不执行任何片段
- loop——片段重复一定次数,可以在临界条件中指示片段重复的条件
- break——如果执行此片段,则放弃序列的其余部分,可以使用临界来指示发生中断的条件
- par——并行处理,片段中的事件可以交错
- critical——指示此片段中的消息不得与其他消息交错,通常是一些原子性操作
- ref——用来在一个交互图中,引用其他的交互图
5. 协作图
协作图也称为通信图,它描述了系统中,对象间通过消息进行的交互,强调了对象在交互行为中承担的角色
协作图包含了 3 个元素
- 对象(Object)
- 链(Link)
- 消息(Message)
序列图与协作图都表示对象之间的交互作用,只是它们的侧重点有所不同
- 序列图描述了交互过程中的时间顺序,但没有明确地表达对象之间的关系
- 协作图描述了对象之间的关系,但时间顺序必须从顺序号获得
- 两种图的语义是等价的,可以从一种形式的图转换成另一种形式的图,而不丢失任何信息
六、状态图
1. 状态图简介
状态图主要用于描述一个对象在其生存期间的动态行为,表现为一个对象所经历的状态序列,引起状态转移的事件(Event),以及因状态转移而伴随的动作(Action)
2. 状态图元素
状态(State)
- 状态指在对象的生命周期中的某个条件或者状况
- 在此期间对象将满足某些条件、执行某些活动或等待某些事件
- 所有对象都有状态,状态是对象执行了一系列活动的结果,当某个事件发生后,对象的状态通常将发生变化
- 在UML中状态用圆角矩形表示
初始状态(Initial State)
- 用实心圆点表示,通常带有已经过初始化的含义
终止状态(Final State)
- 用圆形内嵌圆点表示
转移(Transaction)
- 转移是两个状态之间的一种关系,表示对象将在源状态(Source State)中执行一定的动作,并在某个特定事件发生而且某个特定的警界条件满足时进入目标状态(Target State)
- 转移用带箭头的实线表示
触发事件(Trigger)
- 是转移的诱因
警界条件(Guard Condition)
- 当警界条件满足时,事件才会引发状态转移
结果(Effect)
- 对象状态转移后的结果
动作(Actions)——动作是一个可执行的原子操作,也就是说动作是不可中断的,其执行时间是可忽略不计的
动作分类:EntryActions、DoActions、ExitActions
自身转移(Self-Transition)——状态可以有返回自身状态的转移,称为自身转移
组合状态
嵌套在另外一个状态中的状态称之为子状态,一个含有子状态的状态被称作组合状态
进入节点
- 由于一些原因并不会执行初始化,而是直接通过一个节点进入状态,则此节点称之为进入节点或选择节点
退出节点
- 从状态内部的子状态转移到外部的状态,在边界处要经过退出节点
历史状态
- 历史状态是为了记住从组合状态中退出时所处的子状态,当再次进入组合状态,可直接进入这个子状态,而不是再次从组合状态的初态开始
并发(Synchronization)
- 组合状态在某一时刻可以同时达到多个子状态