包是UML中管理元素的有效手段,UML中的所有元素均隶属于某一个包,即使你没有指定元素所属的包,这些元素也会被置于一个默认包中,包的本质是命名空间。当我们在一个包中需要访问另一个包中的元素时,可以使用符号“::”逐级引用。

例如在下图所示的包图中,存在两支包含多个层次的包,如果包A3中的元素需要访问包B3中的元素C,则可以使用B1::B2::B3::C的形式达到目的。



不同包中的元素进行交互是常态而不是偶发现象,使用符号“::”引用其他包中的元素,特别是在包的层级较深时,元素前面会有长长的由“::”连接的包路径。对人类而言,这种冗长的形式无论是书写还是阅读都是一项具有挑战性的工作,它影响的不只是效率,可读性也大打折扣。为解决这个问题,UML提供了包导入的机制,例如在上面这种情况下,我们可以将包B3导入到包A3中,其图形化表示如下图所示。导入关系使用由导入包发出终止于被导入包的虚线箭头表示,并需要标注“<>”标签。



一旦包B3被导入包A3中,包B3就如同成了包A3的一个虚拟的子包,在遵循可见性规则的前提下,包A3中的元素就像使用子包中的元素一样使用包B3中的元素。在下图中,使用虚线在包A3中描画包B3,表达了这种虚拟的关系。



注:关于UML中可见性的说明,可参见文章《修饰符》中“可见性修饰符”部分。

包的设计本质上应有其内在逻辑含义,但客观上它也是解决命名冲突的一种手段,而通过import向一个包导入另一个包时,如果被导入的包中与当前包中存在同名元素就会产生名称冲突。在这种情况下,被导入包中的冲突元素将被忽略而不被导入,如果需要使用这个产生冲突的元素,我们将不得不继续使用“::”的形式来进行意图表达。这就正如当前包中的元素与子包中的元素名称产生冲突时一样。

如上文所述,将一个包全部导入到另一个包中可能会产生诸如名称冲突或其他潜在问题。如果一个包只使用另一个包中一个或少数几个元素,更好的做法是仅导入那些我们需要的元素。例如包A3仅需要使用包B3中的元素C,则在导入时,可仅导入元素C,在图形描画上,导入箭头直接指向元素C即可,如下图所示。



仅导入需要的元素时,将只有被导入的元素可直接使用,而那些与被导入元素位于同一包的其他元素对当前包则需要继续使用符号“::”引用。在上述示例中,被导入的元素C在使用逻辑上也如同直接在包A3中定义一样,而元素D则是包A3之外位于其他包中的一个普通元素。



仅导入特定元素降低了导入产生潜在问题的可能性,但是也有可能被导入的元素与当前包中的元素碰巧产生了冲突。例如我们要在包A3中导入包B3中的元素C,但包A3中已经包含了一个名为C的元素,导入产生名称冲突。此时,我们可以使用“<> 别名”的形式为导入的元素指定一个别名,在下图中我们使用“<> E”为包B3中元素C指定了在包A3中的别名E,即在包A3中,我们可以使用E代表包B3中的元素C,而使用C时则指包A3中的元素C。



上述对import的说明重点在import使用和细节上,但其实<>表明两个包之间的依赖关系。而包之间的常见依赖关系除导入(import)外,还有访问(access)。访问表明当前包依赖使用被访问的包。例如包B需要使用包A1,则通过由包B出发终止于包A1的并带有标签“<>”虚线描画表示。

在下图中,同时描画了包之间的import和access关系,包B访问包A1而导入包A2。



在UML的场景下,包B中的元素使用包A1和A2并无二致,我们可将包A1与A2均视为包B中虚拟的子包,但这两种依赖关系的效果有一个明显的区别,即“<>”所引入的包A2在包B中的可见性可视为public,而“<>”所表明依赖的包A1在包B中的可见性为private。如果进一步探究这种差异,可以尝试令包C通过“<>”依赖于包B,由于包A1在包B中的可见性为private,故包A1在包C中不可见,而包A2在包B中的可见性为public,故包A2在包C中也等价于被导入,可直接使用。其虚拟效果如下图所示:



在编程时包之间的依赖关系如果设置有误,往往会在程序编译与运行时发生异常,UML仅通过图形表达相关关系,不同UML工具对依赖的检查并不一致,所以需要仔细检查确认。

参考文献:

1.《OCUP 2 Certification Guide_ Preparing for the OMG Certified UML 2.5 Professional 2 Foundation Exam》 Michael Jesse Chonoles

2.《OMG Unified Modeling Language (OMG UML) Version 2.5.1》

UML之包的导入与访问的更多相关文章

  1. [UML]UML系列——包图Package

    系列文章 [UML]UML系列——用例图Use Case       [UML]UML系列——用例图中的各种关系(include.extend)       [UML]UML系列——类图Class   ...

  2. 01Spring_基本jia包的导入andSpring的整体架构and怎么加入日志功能

    1.什么是Spring : v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:u ...

  3. UML之包图

    包图是UML中用类似于文件夹的符号表示的模型元素的组合,系统中的每个元素都只能为一个包所有,一个包可嵌套在另一个包中,使用包图可将相关元素归入一个系统,一个包中包含附属包.图表或单个元素.简单的来说, ...

  4. java:包、继承,访问修饰符

    包 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包可以看出目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维护 [3] 更好的保护类.属 ...

  5. python—day15 包的认识、执行顺序、执行流程、循环导入、包的导入、绝对、相对导入

    一.包的认识   包通过文件夹来管理一系列功能相近的模块 ​ 包:一系列模块的集合体 重点:包中一定有一个专门用来管理包中所有模块的文件 包名:存放一系列模块的文件夹名字 包名(包对象)存放的是管理模 ...

  6. day 16 包的导入

    包的认识 '''包通过文件夹来管理一系列功能相近的模块​包:一系列模块的集合体重点:包中一定有一个专门用来管理包中所有模块的文件包名:存放一系列模块的文件夹名字包名(包对象)存放的是管理模块的那个文件 ...

  7. DAY16 模块和包的导入

    一.包 1.包的定义 包:就是一系列模块的结合体 2.重点 1.包中一定要有一个专门来管理包中所有模块的文件 2.包名:存放一系列模块的文件夹名字 3.包名(包对象)存放的是管理模块的那个文件的地址, ...

  8. Day 16 模块和包的导入

    包的认识 包通过文件夹来管理一些列功能相近的模块 包:一系列模块的集合体 重点:包中一定有一个专门来管理包中所有模块的文件 包名:存放一系列模块的文件夹名字 包名(包对象)存放的是管理模块的那个文件地 ...

  9. python基础(12)-包的导入&异常处理

    包的导入 几种导入方式 import 包名 import time time.time() import 包名,包名 import time,sys time.time() sys.path from ...

  10. Hibernate初探之单表映射——jar包的导入

    编写第一个Hibernate例子需要的基本步骤 创建Hibernate的配置文件 创建持久化类 创建对象-关系映射文件 通过Hibernate API编写访问数据库的代码 使用版本:Hibernate ...

随机推荐

  1. centos7.9 安装 nodejs(包含安装fnm、更换yum源、升级 gcc、make、glibc、libstdc++)

    1.安装fnm (1)压缩包fnm-linux.zip搞到服务器上,我放在root里. (2)解压.设置权限 unzip fnm-linux.zip chmod 777 fnm (3)设置环境变量,添 ...

  2. KubeSphere 社区双周报|2024.02.29-03.14

    KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...

  3. 云原生爱好者周刊:你对 K8s 集群升级有信心吗?

    开源项目推荐 GoNoGo 在 Kubernetes 集群中,有多种因素会影响到附加组件的升级成功率,比如某些组件只支持特定的 API 或者特定的 Kubernetes 版本,某些组件废弃了特定的 a ...

  4. SpringBoot开启Gzip接口报文压缩

    背景 当我们一个接口响应报文比较大的时候,超过几兆甚至几十兆的情况下,减少响应体的报文大小是能有效减少响应时间的. spring boot 配置 server: compression: ## 开启服 ...

  5. 题解 NOIP2014 提高组-联合权值

    题解 NOIP2014 提高组-联合权值 基本思路:以每个点为中转点,则与之相邻的点组成的点对都可产生联合权值,并且全覆盖. 主要总结一下两种求权值和的思路: 思路1(容斥):记与 \(u\) 相邻的 ...

  6. .NET Core 反射底层原理浅谈

    简介 反射,反射,程序员的快乐. 前期绑定与后期绑定 在.NET中,前期绑定(Early Binding)是指在编译时就确定了对象的类型和方法,而后期绑定(Late Binding)或动态绑定是在运行 ...

  7. 终于搞全了:GPIO/ADC/LED/I2C/SPI/USB…

    合宙低功耗4G模组经典型号Air780E,支持两种软件开发方式: 一种是传统的AT指令:一种是基于模组做Open开发. 传统AT指令的开发方式,合宙模组与行业内其它模组品牌在软件上区别不大,在硬件功耗 ...

  8. 定位模组LuatOS快速入门:源UART串口通信

    合宙Air201资产定位模组--是一个集成超低功耗4G通信.语音通话.超低功耗定位.计步.震动.Type-C.充电.放音.录音等功能的超小PCBA. 内部集成高效.简单.可靠的LuatOS语言,旨在帮 ...

  9. 低功耗4G模组:LCD应用示例

    ​ 今天我们学习合宙Air780E开发板LCD应用示例,文末[阅读原文]获取最新资料. 本文档适用于Air780E开发板 关联文档和使用工具 lcd-demo: https://gitee.com/o ...

  10. 高性能的Reactor和Proactor模式学习

    0.引言 在上一篇的笔记中,我们学习了操作系统提供的高效I/O管理技术,主要用于解决服务器在高并发场景下的资源浪费和瓶颈问题.但是在实际的代码编写中,要是我们都全部调用底层的I/O多路复用接口来编写网 ...