UML _ 包图
模型组织与系统结构
对一个较复杂的系统建模,需要使用大量的模型元素,这就有必要对这些元素进行有效组织。
实现
在UML的建模机制中,模型的组织是通过包(Package) 来实现的。
包可以把所建立的各种模型组织起来,形成各种功能或用途的模块,并可以控制包中元素的可见性以及描述包之间的依赖关系。
作用
方便在高层(按照模块的方式)把握系统的结构。
系统结构
对于系统模型的内部组织结构而言,通常采用先分层、再细分成包的方式。
分层一般是按系统架构,常用的一种方式是三层架构:
-
用户界面层(User Interface Layer , UIL,也称为表示层PL):
代表与用户进行交互的界面,既可以是Form窗口,也可以是Web界面(网页) ;不处理任何业务,负责显示与实时更新。 -
业务逻辑层(Business Logic Layer, BLL):
负责系统的业务流程,处理数据访问层传送的数据,并实现业务逻辑。
【例如:界面login.html,业务login(input1,input2) ,数据访问getData(uid,pwd) 】 -
数据访问层(Data Access Layer, DAL):
与数据库进行交互,负责将底层数据传送到业务逻辑层。
MVC设计模式——Model、View、Controller
-
模型层
是对系统应用功能的抽象,代表了数据和业务规则;包中的类通常用于封装系统的数据及数据的存取操作。 -
视图层
是对系统数据表达的抽象,代表了系统界面内容的显示;在包中的各个类对用户的数据进行表达,并维护数据的一致性。 -
控制器层
是对用户与系统交互事件的抽象,协调Model与View;通常负责从视图读取数据,控制用户输入,并向模型发送数据。
概述
包
定义:
包(Package)是用于把模型本身组织成层次结构的机制,可以将多个元素组织为语义相关的组。
注意:
-
包是对模型元素进行分组的机制,它不能执行。
-
所有的UML模型元素都能用包来进行组织,但一个元素只能属于一个包。
-
包经常用来组织类图、顺序图、活动图等数量较多的相关元素。
作用
包是UML中最重要的分组事物,用来组织模型中的元素。
具体作用如下:
-
对语义上相关的元素按一定规律进行分组。
例如,把功能相关的类放在一个包中。 -
提供封装的命名空间。
同一个包中,元素不能重名,其元素的名称必须惟一。 -
提供配置管理单元。
例如,以包为单位,对软件进行安装和配置。 -
在设计时,提供并行工作的单元。
例如,在设计阶段,多个设计小组,可以同时对几个相互独立包中的类进行详细设计。
包图
注意:
包图uml1是非正式图,但是大量使用,uml2是正式图。
定义
包图(Package Diagram)是用来描述模型中的包及其关系的图。
包图是一种维护和描述系统总体结构的模型,是分析和设计阶段的成果。
通过对图中各个包以及包之间关系的描述,展现出系统的模块与模块之间的依赖关系。
包图的作用
包图是一种维护和描述系统总体结构的模型,是表示顶层架构的机制。
-
在逻辑上把一个复杂的系统模块化:
反映系统的高层架构,在逻辑上将系统进行模块化分解; -
描述需求的高阶概况:可以通过包来简要描述系统的业务需求;
-
描述设计的高阶概况:可以通过包来组织系统的业务设计模型和框架模型;
-
描述源代码的组织方式:在实际应用中,包是组织源代码的方式。
分包原则
-
重用等价原则:把类放入包中时,应考虑把包作为可重用的单元,即要求新版本的可重用类容易替换旧版本的可重用类。
-
共同闭包原则:把可能同时修改、同时维护的类放到一个包中,以便于维护和升级。例如:
一个类的改变要求另一个类做相应改变;
删除一个类后,另一个类变成多余;
两个类间有大量的消息发送。 -
共同重用原则:通常,一个包中的元素(类)要么都可重用,要么都不可重用。不会一起使用的类,不要放在同一个包中。
-
“高内聚低耦合”的原则
A:包内元素要紧密联系;最大化每个包中private元素的个数。
B:包与包尽可能保持独立,最大限度减少包之间的依赖;最小化每个包中public、protected元素的个数。 -
非循环依赖原则:包之间不要形成循环依赖关系;循环依赖是由于分包不当造成的。
如果出现,解决方法: 合并法和分离法
包图的组成
- 包
- 依赖关系
- 泛化关系
- 拥有(组成)关系 没有符号,就是指大包里面有小包的情况
包
包用来组织模型中的元素,其功能类似于操作系统中的文件夹,在图形上被表示为一个文件夹的形状。
包的名称
包的名称通常是来自模型词汇中的名词或名词短语。
表示方法:
简单名:只是一个单独的名称。
路径名(限定名):用该包的外围包(上层包)的名字作为前缀,加上用双冒号(::)
分隔的包本身的名字。
也有用from表示 包 (from 上层包)
注意
-
一个包内同一类模型元素的名字必须是唯一的,不能重名;
-
理论上,一个包中不同类的模型元素可以有相同的名字。(实际上有的、软件支持有的软件不支持)
-
最好一个包中的所有元素都有唯一的命名
包中可以拥有的元素:
在一个包中可以创建所有模型元素,如类、图以及子包等。
注意
-
每个元素只能属于一个包。
-
在包图下允许创建的各种模型元素,是根据各种视图下所允许创建的内容决定。
表示
一般有两种表示方法,如下图:
包的嵌套
包可以拥有其他包作为包内的元素,这被称为包的嵌套。
外围包(容器包)中包含子包,子包又可以拥有自己的子包。
注意:
-
包的嵌套层数没有限制,但是一般以2到3层为宜。
-
不同的包中模型元素名称可以相同
包内元素的可见性
包内元素的可见性,控制了包外部元素访问包内部元素的权限。
关键字 | 符号 | 语义 |
---|---|---|
public | + | 公共元素对包内外元素都可见(所有引入的包以及它们的后代) |
private | - | 私有元素只对包内元素(不包含内部子包)是可见的 |
protected | # | 受保护元素除对包内元素可见外,还对与当前包具有泛化关系的包可见 |
package | ~ | 仅对同一包内声明的模型元素是可见的(对嵌套在该包内的所有包均可见) |
UML常见的内置构造型
包有不同的构造型,表现为不同的特殊类型的包。
-
<<system>>
和<<subsystem>>
构造型
系统和子系统包 -
<<facade>>
构造型
(外观)构造型的包,自身不包含任何模型元素,只是引用其他包的元素,所以称为“虚包”,主要用于为其他复杂的包提供简略视图。 -
<<stub>>
构造型
(桩)构造型的包,是一个代理包,通常应用于分布式系统的建模中,作为其他包的公共内容代理的包。
注意:可以自定义构造型。
关系
依赖关系
两个包之间最常见的关系就是依赖关系,是指两个包所包含的模型元素之间存在着一个或多个依赖。
分类:
包之间的依赖有四种:use、import、access、trace
注意
- 引入依赖和访问依赖比较常见。
- 四个都是构造型
表示方法
依赖关系用带箭头的虚线表示,箭头从客户包指向提供者包。
use关系
use 关系是一种默认的依赖关系 ;因此use可以在建图时,不指出构造型
说明客户包中的元素以某种方式使用提供者包的公共元素,也就是说客户包依赖于提供者包。
import关系
import关系使命名空间合并,是最常见的依赖关系。
import(引入/导入)关系说明
- 提供者包的命名空间将被添加到客户包的公共命名空间中;
- 客户包中的元素能够访问提供者包的所有公共元素;
注意:
-
引入依赖是可以传递的
-
客户包的元素可以使用简单名引用提供者包的元素,但提供者包的元素不能与客户包的元素同名,否则将会导致命名空间的冲突。
例子:
access关系
access(访问)关系说明
- 客户包中的元素能访问提供者包中的所有公共元素
但是命名空间不合并,仅把提供者包的内容附加到客户包的私有命名空间,
在客户包中必须使用路径名。
引入和访问 比较
不同点
-
import关系使命名空间合并,访问依赖包的元素直接使用简单名即可。
-
access关系不合并命名空间,必须要使用路径名访问依赖的包的元素。
例子
Client直接通过简单名使用Policies和GUI中可见性为公共的模型元素(引入依赖是可以传递的)
Client只能通过路径名的方式,使用GUI中的公共元素
注意:命名空间合并相当于合并成一个包,因此如果两者都是使用access关系。Client不能访问GUI中的元素
相同点
公共命名空间里的模型元素可以被其他包使用,而私有命名空间中的模型元素则不可以。
也就说import和access都不能使用其他包的私有属性,他们两个对其他包的内容的访问权限是一样的。
trace关系
追踪(追溯),表示一个包到另一个包的历史发展,
例如不同版本的包。
泛化关系
和其他泛化关系一样,两包是泛化关系意味着:
-
特殊包继承一般包的特性,使用一般包的地方,可以用特殊包代替。
-
特殊包继承一般包中公共和受保护可见性的模型元素,此外还可以添加新的元素。
箭头指向: \(特殊包(子包)\to 一般包(父包)\)
常见使用场景:
例如,在系统设计中,对某一个特定的功能有多种实现方法。这时可以定义一些高层次的“抽象包” 和 实现高层次功能的“实现包”。
- 抽象包定义一些接口和抽象类;
- 实现包定义包含实现这些抽象类和接口的具体类,还可以增添新的元素。
表示
注意
任何可使用父包的地方都可以使用子包代替
拥有关系
没有关系符号,语义上的关系。
拥有关系是包嵌套时,包之间的一种组成关系,意味着子包被外围包所拥有。
包图的建模技术
对成组元素建模
这是包图最常见的用途,它将建模元素组织成组,建模成包,然后对包进行命名。这种策略在对建模大型项目时尤为重要。
大多数情况下,用包组织种类相同的元素,也可以组织不同种类的元素。
遵循的策略
-
找出在概念或语义上接近的元素,组织到一个包中,同时考虑必要的嵌套包。
-
对每个包确定包内元素的可见性,重点找出应标记为公共的元素,但应尽可能地少。
-
在包之间建立关系时,初期一般使用默认的
<<use>>
构造型,在映射到编程时考虑明确<<import>>
或<<access>>
构造型。 -
考虑采用泛化来对特殊包进行建模
例:
对体系结构视图建模
体系结构是一个软件系统的核心逻辑结构,是对系统的顶层分解。
例如:三层架构、MVC模式。
视图是对系统的组织和结构的某个方面的投影,表达了对系统某个方面的关注。
实际上:现在绝大部分的UML建模工具的视图结构,都是使用包元素来划分其体系结构视图的。
例如: RUP的“4+1”视图。
遵从的策略:
- 识别出问题域中一组有重要作用的体系结构视图。
- 把每个视图的语义充分且必要的元素放到适当的包中。
- 如有必要,进一步把这些元素组织到它们各自的包中。
例:
三层架构
4+1视图
建模步骤
包图建模的基本过程主要有四个步骤:
-
根据系统架构需求,确定分包原则
-
寻找并创建包—分析系统工作流程
-
确定包之间的关系
-
标出包内元素及其可见性
包图的绘制
-
创建包图
-
创建包
-
设置包中元素
向包中添加元素
在包中显示包含的元素 -
创建包的关系
-
细化包内元素及包间关系
注意事项
-
通过把具有很强语义联系的建模元素分组,找出分析包;
-
包的命名要简单、具有描述性;
-
应尽量避免包模型中的循环依赖;
-
良好包结构的关键是包内高内聚、包间低耦合;
(包内元素要紧密联系,包与包之间尽可能保持独立,依赖关系要尽可能少) -
应尽可能避免嵌套包;
-
内容要均衡,建议每个包有7±2个内层成分。
系统中的各个包彼此相称,既不要太大(必要时可进行分解),
也不要过小(必要时可把所处理的元素组合成组)。
实例
【例】学生信息管理系统
1. 根据系统架构需求,确定分包原则
分析学生信息管理系统,采用MVC架构进行包的划分。
2. 寻找并创建包
根据MVC架构的特点,可以在逻辑视图下确定三个包,分别为模型包Model、视图包View和控制包Controller。
3. 确定包之间的关系
4. 标出包内元素及其可见性
【例】股票交易系统
1. 根据系统架构需求,确定分包原则
需求:
- 通过Internet连接到股票信息服务器,获取实时的股票信息,并存入数据库中;
- 根据用户的输入和选择,从数据库中获取相应的信息,展现在屏幕中;
- 在数据的展现过程中,将需要绘制大量的图表。
根据需求,可以按照功能模块组织包,分为四个包。
2. 寻找并创建包—分析系统工作流程
3. 确定包之间的关系