(19条消息) UML笔记_半路出家的码农小王的博客-CSDN博客
uml结构
构造块:基本UML建模元素、关系和图
公共机制:达到特定目标的公共UML方法
构架:系统架构的UML视图
构建块
事物:UML模型中最基本的构成元素,是具有代表性的成分的抽象
关系:把事物联系在一起,关系说明两个或多个事物时如何语义相关的
图:事物和关系的可视化表示,它们展现事物的集合,“讲述关于软件系统的故事”,是可视化系统将做什么(分析级图)或者系统如何做的方法(设计级图)
(1)4个事物:结构、行为、分组、注释
(2)4个关系:依赖、关联、泛化、实现
(3)9种图:静态图(用例图、类图、对象图、组件图、部署图);动态图(序列图、协作图、状态图、活动图)
结构事物
(1)类(Class):类是指具有相同属性、方法、关系和语义的对象的集合。
(2)接口(Interface):接口是指类或组件所提供的服务(操作),描述了类或组件对外可见的动作。
(3)协作(Collaboration):协作描述合作完成某个特定任务的一组类及其关联的集合,用于对使用情形的实现建模。
(4)用例(Use Case):用例定义了参与者(在系统外部与系统交互的人或系统)和被考虑的系统之间的交互来实现的一个业务目标。
(5)活动类(Active Class):活动类的对象有一个或多个进程或线程。活动类和类很相象,只是它的对象代表的元素的行为和其他的元素是同时存在的。
(6)组件(Component):组件是物理的、可替换的部分,包含接口的集合,例如COM+ 、JavaBean等。
(7)结点(Node):结点是系统在运行时存在的物理元素,代表一个可计算的资源,通常占用一些内存和具有处理能力。
关系
UML的关系是将UML的事物联系在一起的方式,UML中定义了四种关系:
(1)依赖关系(Dependency):两个事物之间的语义关系,其中一个事物发生变化会影响另一个事物的语义。
(2)关联关系(Association):描述一组对象之间连接的结构关系,如聚合关系就描述了整体和部分间的结构关系。
(3)泛化关系(Generalization):一般化和特殊化的关系。
(4)实现关系(Realization) :类之间的语义关系,一个类说明一份契约,另一个类保证实现该契约。
图
面向对象
面向对象方法具有以下几个要点:
(1)面向对象的软件系统是由对象组成的,软件中的任何元素都是对象,复杂的软件对象由比较简单的对象组合而成。
(2)把所有对象都划分成各种对象类,每个对象类都定义了一组数据和一组方法,数据用于表示对象的静态属性,是对象的状态信息。
(3)按照子类与父类的关系,把若干个对象类组成一个层次结构的系统。
(4)对象彼此之间仅能通过传递消息进行联系
对象和实例
•对象(Object) 有意义的一切事物都是对象
–它是系统用来描述客观事物的一个实体,是构成系统的一个基本单位。
–对象包括:属性(静态特征)和方法(动态特征)
–对象之间通过消息进行通信。
• 对象不仅能表示具体的实体,也能表示抽象的规则、计划或事件。主要有如下的对象类型:
• (1)有形的实体:如汽车、书、计算机。
• (2)作用:如医生、教师、员工、学生。
• (3)事件:如飞行、事故、中断、开会等。
• **(4)性能说明:**如车厂对车辆的性能说明,往往要列出型号及各种性能指标等。
类
•实例(Instance)
–它与对象的概念很类似,但其含义更广泛一些。
•类(Class)
–它是具有相同属性和方法的一组对象的集合
–为某类对象提供统一的描述
–类是静态概念,对象是动态的
–对象是类的实例
•封装(Encapsulation)
–就是把对象的属性和方法结合成一个独立的系统单位,并尽可能隐蔽对象的属性、方法和实现细节的过程。
–封装使对象具有2个部分:接口部分和实现部分
实现部分:保证内部信息是隐藏的
接口部分:外界只能通过指定的接口与对象联系
封装是实现数据隐藏的有效手段,可以保证数据结构的安全性。提高了系统的可维护性和可移植性
•继承(Inheritance)
–它使子类可以继承父类的属性和方法
–继承增加了软件复用的机会
•单继承与多继承
•单重继承:指的是一个子类只有一个父类;
• 多重继承:指的是一个子类可以有多个父类。
在继承中,需要明确这样两个概念,子类和父类。
子类:指的是通过继承创建的新类,称为“子类” 或者“派生类”。也可以增加自己的特殊属性和方法。
父类:指的是被继承的类称为“基类”、“ 父类” 或“ 超类”
•多态(polymorphism)
–在OO技术中,多态指使一个实体在不同上下文条件下具有不同意义或用法的能力
多态性是指类中同一函数名对应多个功能相似的不同函数,可以使用相同的调用方式来调用这些具有不同功能的同名函数,这些同名的函数可以是参数的个数或是类型不同,但是函数名相同,当进行调用的时候,根据所传的数据选定相应的函数,从而去执行不同的功能。
与多态有关的概念
–继承
–覆盖
–动态绑定
向上转型(指派)
•覆盖(override):在子类中增加或重新定义所继承的属性或方法。
public class A{
String name;
public String getValue(){
return “Value is:” + name;
}
}
public class B extends A {
String address;
public String getValue () {
return “Value is:” + address;
}
}
重载(overload):同一个类中有多个同名方法,但它们在操作数或操作数类型上有区别。系统根据实参引用不同方法。
•消息(Message)
–是指向对象发出的服务请求
–对象直接用消息的方式传递信息,而不是参数
–消息是实现对象之间进行通信的一种机制,对于一个对象可以接收不同形式的多个消息,并产生不同的结果;相同形式的消息可以发送给不同的对象,并产生不同的结果;在发送消息的时候可以不考虑具体的接收者,对象可以对消息做出响应,也可以拒绝消息,也就是说不是必须要对消息做出响应。
•面向对象分析OOA
–用面向对象方法分析问题域,建立基于对象、消息的业务模型,形成对客观世界和业务本身的正确认识。
–生成业务对象的动、静态模型和抽象类 UML业务模型、用例图以及初步的交互图。
•面向对象设计OOD
–针对OOA给出的问题域模型,用面向对象方法设计出软件的基础架构(概要设计)和完整的类结构(详细设计),以完成业务功能。最后编码。
–生成对象类的动、静态模型(解决域) UML类图、交互图(顺序图和协作图)、状态图、活动图以及实施阶段的组件图和部署图。
用例图
1、用例图定义
表示一个系统中用例与参与者关系之间的图,描述系统中相关用户和系统对不同用户提供的功能和服务(从用户视角描述,分析系统功能与行为)
2、用例图构成
(1)参与者(Actor)
(2)系统边界(System scope)
(3)用例(Use case)
(4)关联(Association)
此外,用例图还可以包括注解和约束,也可以使用包将图中的元素组合成模块。
参与者
概念
- 参与者是与系统主体交互的外部实体的类元,描述了一个或一组与系统产生交互的外部用户或外部事物。
- 参与者位于系统边界之外,而不是系统的一部分。
- 参与者是从现实世界中抽象出来的一种形式,却不一定确切对应的现实中的某个特定对象
处于用例的外部,可以是人或其他外界系统
参与者确定方法
- 使用系统主要功能的人(主要角色)
- 借助系统完成日常工作的人
- 维护、管理系统的人(次要角色)
- 硬件设备、其他系统交互、对系统结果感兴趣的人或事
用例
用例的概念
用例是类元提供的一个内聚的功能单元,表明系统与一个或多个参与者之间信息交换的顺序,也表明了系统执行的动作。
简单来说,用例就是某一个参与者在系统中做某件事从开始到结束的一系列活动的集合,以及结束时应该返回的可观测、有意义的结果,其中也包含可能的各种分支情况。
用例与用例图被广泛使用于系统的需求建模阶段,并在系统的整个生命周期中被不断细化。
关系
•包含(include)
包含指的是一个用例(基用例)可以包含其他用例(包含用例)具有的行为,其中包含用例中定义的行为将被插入基用例定义的行为中。
包含的两个基本约束:
1.基用例可以看到包含用例,并需要依赖于包含用例的执行结果,但是它对包含用例的内部结构没有了解;
2.基用例一定会要求包含用例执行。
包含表示为一个虚线箭头附加上《include》的构造型,箭头从基用例指向包含用例。
•扩展(extend)
扩展指的是一个用例(扩展用例)对另一个用例(基用例)行为的增强。
扩展使用一个附加了《enxtend》构造型的虚线箭头表示,箭头指向基用例。
注意:扩展与包含的箭头方向是相反的,这表明扩展取决于扩展用例而非基用例,扩展用例决定扩展的执行时机,基用例对此一无所知。扩展用例的使用包括四个部分:
- 基用例:需要被扩展的用例,“注册”用例。
- 扩展用例:提供所添加的行为序列的用例。
- 扩展关系:使用虚线箭头表示,箭头指向基用例。
- 扩展点:基用例中的一个或多个位置,表示在该位置会根据某条件来决定是否要中断基用例的执行从而执行扩展用例中的片段。
•泛化(generalization)
与参与者的泛化关系相似,用例的泛化关系将特化的用例与一般化的用例联系起来。子用例继承了父用例的属性、操作和行为序列,并且可以增加属于自己的附加属性和操作。父用例同样可以定义为抽象用例。
用例之间的泛化关系表示为一根实线三角箭头,箭头指向父用例一方。
包含、拓展的区别
用例描述与文档
用例描述概述
一个完整的用例模型应该不仅仅包括用例图部分,还要有完整的用例描述部分。
一般的用例描述主要包括以下几部分内容:
-
用例名称:描述用例的意图或实现的目标,一般为动词或动宾短语。
-
用例编号:用例的唯一标识符,在其他位置可以使用该标识符来引用用例。
-
参与者:描述用例的参与者,包括主要参与者和其他参与者。
-
用例描述:对用例的一段简单的概括描述。
-
触发器:触发用例执行的一个事件。
-
前置条件:用例执行前系统状态的约束条件。
-
基本事件流(典型过程):用例的常规活动序列,包括参与者发起的动作与系统执行的响应活动。
-
扩展事件流(替代过程):记录如果典型过程出现异常或变化时的用例行为,即典型过程以外的其他活动步骤。
-
结论:描述用例何时结束。
-
后置条件:用例执行后系统状态的约束条件。
-
补充约束:用例实现时需要考虑的业务规则、实现约束等信息。
·前置条件与后置条件
前置条件指的是用例执行前系统和参与者应处于的状态。前置条件是用例的入口限制,它便于我们在进行系统分析及设计的时候注意到,在何时何地才可以合法地触发这个事件。
后置条件是用例执行完毕后系统处于的状态。后置条件是对用例执行完毕后系统状况的总结,用来确保用户理解用例执行完毕后的结果,并非其他用例的触发器。
前置条件与后置条件分别是用例在开始和结束时的必要条件。
·事件流
事件流是对用例在使用场景下的交互动作的抽象,应该包括用例何时以及怎样开始和结束,用例何时与参与者交互,该行为的基本流和可选择的流。
基本事件流:描述的是用例中最核心的事件流,是用例大部分时间所进行的场景。
扩展事件流:描述的是用例处理过程中的一些分支或异常情况。
·补充约束
补充约束用来描述用例在系统功能之外的内容,例如非功能需求、业务规则等等。
数据需求:与该用例相关的一些数据项的说明。
业务规则:与业务相关的逻辑和操作规则。
非功能性需求:例如性能、支持的并发量等。
设计约束:是从多个角度对用例或系统的约定。
·用例文档实践
·用例图使用要点
构建结构良好的用例。用例图中应该只包含对系统而言必不可少的用例与相关的参与者。
用例的名称不应该简化到使读者误解其主要语义的程度。
摆放元素时应尽量减少连接线的交叉,以提供更好的可视化效果。
组织元素时应使在语义上接近的用例和参与者在图的位置上也同样接近,便于读者理解用例图。
可以使用注解或给元素添加颜色等方式突出图中相对重要的内容。
用例图中不应该有太多的关系种类。
·用例图建模技术
对系统的语境建模
识别系统边界。
识别参与者。
如果需要,将具有相同特征的参与者使用泛化关系加以组织。
如果需要,对某些参与者应用一个构造型以便加深理解。
将参与者应用到用例图中,并描述参与者与用例间的通信路径。
对系统的需求建模
识别参与者。
对于某个参与者,考虑其期望系统提供的行为或与系统的交互。
将行为提炼成用例。
完善其他用例。分解用例中的公共行为与扩展行为,放入新的用例中以供其他用例使用。
创建用例图。
如果需要,在用例图中添加一些注解或约束来陈述系统的非功能需求。
案例——学生选课系统
某学校的网上选课系统主要包括如下功能:
管理员通过系统管理界面进入,建立本学期要开的各种课程,将课程信息保存在数据库中并可以对课程进行改动和删除。
学生通过客户机浏览器根据学号和密码进入选课界面,在这里学生可以进行三种操作:查询已选课程,选课以及付费。
同样,通过业务层。这些操作结果存入数据库中。
步骤:
确定系统边界
确定参与者(名词)
确定用例(动宾结构)
确定关系(联系)
参与者:学生、教务人员、数据库
用例:选课、查询、支付课时费用、登陆、修改课程、添加课程、删除课程
关系:关联关系、泛化关系
类图
类图的定义:是显示一组类、接口、协作以及它们之间关系的图。
类图主要包含7种元素:类、接口、协作、依赖关系、泛化关系、实现关系、关联关系。
类图:包、子系统,用来把模型元素聚集成更大的组块。
类图:约束、注解
•类图用于建立类、类的内部结构以及类与类相互之间的各种关系模型。类图由类、类之间的关系和约束组成。
•类图=类+关系+约束
•类图是UML建模中最基本和最重要的一种图。
•在程序设计的不同阶段,类图的作用也不相同
•分析阶段:主要用于描述概念类
•设计阶段:主要用于描述类的外部特征
•实现阶段:主要用于描述类的内部实现
类
- 类是一组拥有相同的属性、操作、方法、关系和行为的对象地描述符。
- 类定义了一组有着状态与行为的对象。类的状态由属性和关联来描述,个体行为由操作来描述,对象的生命周期则由附加给类的状态机来描述。
- 在UML中,类表达成一个有三个分隔区的矩形。其中顶端显示类名,中间显示类的属性,尾端显示类的操作。
属性
•属性:描述该类的对象所具有的特征
•属性的格式:
•[可见性] 属性名 [:类型][‘[’多重性[次序]’]’][=缺省值][{特性}]
•可见性:表示一个方法或属性是否能被另一个方法访问
•多重性:属性值个数格式,多重性::=[低…高]**
•次序:属性值顺序
•特性:对该属性性质的一个约束说明,如{只读}
公共:类的属性和方法对其他模型元素都是可访问的。公共的可见性应该尽量少用,公共就意味着将类的属性和方法暴露给外部,这与面向对象的封装原则是相矛盾的。
保护:属性和方法只对类本身、它的子类或友元是可看见的。保护可见性是默认的可见性。它保护属性和方法不被外部类使用。
私有:属性和方法只对类本身和类的友元是可见的。私有的可见性可以用在不希望子类继承属性和方法的情况下。
子类无法继承和访问父类的私有属性和实现属性
接口
- 接口是一个被命名的操作集合,用于描述类或组件的一个服务。
- 接口不包含属性与方法实现,但可以有一些操作。接口的所有内容都是公有的。
- 接口代表了一份契约,实现该接口的类元必须履行它。
- 在UML中,接口由一个带名称的小圆圈表示;也可以表示为带有<>构造型的类
类图中的关系
关联关系
关联的实例被称为链,每个链由一组有序或无序的对象组成。
关联关系靠近被关联元素的部分称为关联端,关联的大部分描述都包含在一组关联端的列表里,每个端用来描述关联中类的对象的参与
二元关联、自关联、N元关联。
•关联的种类
–一般关联:有二元关联和N元关联,关联语义较弱
–聚合:关联语义较强:has-a关系,表示整体和部分的关系,个体可以属于多个整体。(聚合是特殊的关联)
–组合:关联语义强:contains-a关系,整体和部分的关系,个体唯一属于一个整体。部分和整体具有相同的生命周期。
组合关系中的“整体”控制着“部分”的生存期。组合是一种特殊的聚合关系,又称强聚合。
–自身关联:一个类与其自身存在一种关联关系,自关联关系意味着该类的某个实例与该类的其他实例之间存在关联关系。
派生关联:一个关联是由另外的关联推导出来的,派生关联前面加斜杠表示。生成代码时,派生关联不产生相应代码
•受限关联
–在关联端紧靠源类图标处可以有限定符(qualifier),带有限定符的关联称为受限关联或限定关联。
–限定符的作用就是在给定关联一端的一个对象和限定符之后,可以唯一确定另一端的一个对象或对象集。
受限关联用于一对多或多对多的关联。将目标类的多重性从“多”降为“一”
注意要点
关联名称:放在关联路径的旁边,但远离关联端。
角色:放在靠近关联端的部分,表示该关联端连接的类在这一关联关系中担任的角色。角色名上也可使用可见性修饰符号。
多重性:放在靠近关联端的部分,表示在关联关系中源端的一个对象可以与目标类的多少个对象之间有关联。
导航性:一个布尔值,用来说明运行时刻是否可能穿越一个关联。
限定符:是二元关联上的属性组成的列表的插槽,其中的属性值用来从整个对象集合里选择一个唯一的关联对象或者关联对象的集合。
约束:关联间的约束关系。
现实例子
比如客户和订单,每个订单对应特定的客户,每个客户对应一些特定的订单;再例如公司和员工,每个公司对应一些特定的员工,每个员工对应一特定的公司。(表示有关联,也可以表示多重性)
派生关联:属于一种派生元素。它不增加语义信息,只是一种可以由两个或两个以上的基础关联推算出来的虚拟关联。
两种特殊的关联关系:聚合关系与组合关系
1.聚合关系:描述“整体-部分”的关联关系
聚合关系没有改变整体与部分之间整个关联的导航含义,也与整体和部分的生命周期无关。(部分与整体相互独立)
2.组合关系:描述“整体-部分”的关联关系
组合关系中的部分要完全依赖于整体。
关联与聚合的区别
关联关系所涉及的两个对象是处在同一个层次上的。比如人和自行车就是一种关联关系,而不是聚合关系,因为人不是由自行车组成的。聚合关系涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。比如:电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
对于具有聚集关系(尤其是强聚集关系)的两个对象,整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失,部分也就随之消失。比如张三的电脑被偷了,那么电脑的所有组件也不存在了,除非张三事先把一些电脑的组件(比如硬盘和内存)拆了下来。
聚合与组合的区别
聚合关系:涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。比如:电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
组合关系:代表整体的对象负责代表部分对象的生命周期。公司不存在,部门也没有意义了。再例如:人和五脏六腑、四肢的关系。
泛化关系
泛化关系定义为一个较普通的元素与一个较特殊的元素之间的类元关系。其中描述一般的元素称为父,描述特殊的元素称为子。(子类是父类的继承,则父类就是子类的泛化。)
通过泛化对应的继承机制使子类共享父类的属性和操作,小了模型的规模,同时也防止了模型的更新所导致的定义不一致的意外。
泛化关系的特征:
-
传递性:一个类子类的子类同样继承了这个类的特性。在父方向上经过了一个或几个泛化的元素被称为祖先,在子方向上则被称为后代。
-
反对称性:泛化关系不能成环,即一个类不可能是自己的祖先和自己的后代。
泛化关系的两种情况
-
单继承:每个类最多能拥有一个父类。编程语言:C#、Java等
-
多重继承:子类可以有多个父类并继承了所有父类的结构、行为和约束。编程语言:C++等
依赖关系
依赖关系表示的是两个元素之间语义上的连接关系。对于两个元素X和Y,如果元素X的变化会引起对另一个元素Y的变化,则称元素Y依赖于X。其中,X被称为提供者,Y被称为客户。
现实例子:比如说你要去拧螺丝,你是不是要借助(也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作。
对于类图而言,主要有以下需要使用依赖的情况:
-
客户类向提供者类发送消息。
-
提供者类是客户类的属性类型。
-
提供者类是客户类操作的参数类型。
实现关系
实现关系用来表示规格说明与实现之间的关系。在类图中,实现关系主要用于接口与实现该接口的类之间。
一个类可以实现多个接口,一个接口也可以被多个类实现。
实现关系的两种表示法:
-
当接口元素以带构造型的类的方式表示时,用虚线三角形箭头表示。
-
当接口元素以小圆圈方式表示时,用实线表示。
综合例子
对象图
对象图概述:对象图显示了某一时刻的一组对象及它们之间的关系。
对象图可以看做是类图的实例,用来表达各个对象在某一时刻的状态。
建模元素主要有对象和链,对象是类的实例,链是类之间的关联关系的实例。
对象图的组成元素——对象
对象是类的实例,是一个封装了状态和行为的具有良好边界和标识符的离散实体。对象通过其类型、名称和状态区别于其他对象而存在。
对象名:在矩形框的顶端显示。
类型:具体的类目
状态:由对象的所有属性以及运行时的当前值组成。
表示法:在对象名后跟一个冒号加上类型名,并且使用下划线与类进行区分。
对象图的组成元素——链
链是关联关系的实例,是两个或多个对象之间的独立连接。因此,链在对象图中的作用就十分类似于关联关系在类图中的作用。
在UML中,链同样使用一根实线段来表示。
链主要用来导航。链一端的一个对象可以得到另一位置上的一个或一组对象,然后向其发送消息。链的每一端也可以显示一个角色名称,但不能显示多重性。
对象图的建模技术:
为对象结构建模识别建模机制。建模机制被描述为系统的某些功能或行为,经常会被耦合为用例,由一组类、接口和其他事物的交互产生。可以创建协作来描述机制。
识别参与的类和接口等元素,以及这些元素之间的关系。
识别并选择对象。考虑这个机制的脚本在某时刻被冻结时的情况,识别并选择出各个对象。
按需要显示每个对象的状态。
识别并显示出对象之间的链,即对象的类目之间关联的实例。
对象图的建模步骤:
1、确定对象及对象状态(从类图中来)
2、建立链(从类图中来)
对象图使用要点:
1)注重于表达系统静态设计视图或静态交互视图的一个方面。
2)表示由一个交互图描绘的动态场景的一个画面。
3)只包含对理解该方面不可缺少的那些元素。
4)提供与它的抽象层次相一致的细节,应该只显露出对理解是不可缺少的那些属性值和其他修饰。
包图
包图的基本概念: 包图是用来描述模型中的包和所包含元素的组织方式的图,是维护和控制系统总体结构的重要内容。
包图能够组织许多UML中的元素,不过其最常用的用途是用来组织用例图和类图。
包图中包含包元素以及包之间的关系。与其他图类似,包图中可以创建注解和约束。
元素:包中可以容纳各种高级的模型元素,如类和类的关系、状态机、用例图、交互、协作等,甚至是一个完整的UML图。包中还可以含有包,这被称为包的嵌套。
包元素的可见性:
公有(+):只要当前包被引入,包内的公共元素即对引入者可见。
保护(#):仅对当前包的子包可见。
私有(-):仅对该包可见,外部无法访问。
包的构造型:可以使用构造型来描述包的种类。UML预定义了一些构造型,用户也可自行定义新的构造型。
高内聚,低耦合:
在外部观察包时,可以将内部元素视作一个整体,方便将多个元素一同处理。
包内部的元素应该保证有相似、相同的语义,或者其元素有同时更改和变化的性质。
注:在实际应用中,包对包含的元素的作用相当于C++和C#中命名空间的概念或Java中的包概念。和这些概念不同的是,UML包中的内容不限于类和接口,包中的元素种类要丰富的多。
元素的分包原则:
1)元素不能“狡兔三窟”:树形结构的一个节点不能同时拥有两个父节点,一个元素也不允许在两个包中重复出现。
2)相同包内元素不能重名
3)包内元素要紧密联系:分在同一个包中的元素应该具有某些相同的性质,即包的高内聚性。
4)包与包尽可能保持独立:包和包之间需要尽可能减少耦合度,要求包内元素与外部元素有尽可能少的依赖关系。
包的依赖关系:
包之间的依赖关系实际上是从一个更高的层次来描述包内某些元素之间的依赖关系。也就是说,如果不同包中任何元素之间存在着一个依赖,则两个包之间就存在着依赖关系。
包之间的依赖关系首先需要包中的某些元素具有某种外部可见性,即可以被包外部的元素所引用。
容易出现的问题:循环依赖
循环依赖的出现是令人困惑、也是非常容易产生错误的。尤其是当依赖关系表示包的引入时,循环依赖会导致将模型转化成代码后因为包之间互相引入而出现错误。
解决方案:重新分包,引入第三个包,重新建立依赖关系。
包图的建模技术
对成组元素建模
- 浏览模型中的元素,找出概念或语义上接近的元素分组。
- 将分好组的元素组织在一个包里,同时考虑包的嵌套。
- 对每一个包,区分哪些元素需要在包外被访问,进而确定包内元素的可见性。这一步骤类似于类的封装过程:没有必要对外开放的元素一定要预先标注为私有,随后逐一检查,如果必须开放再考虑开放可见性为受保护或公有。若设计完成时发现部分公有元素未被使用,还应该将这些元素重新置为私有元素。
- 使用引入依赖显式地在包之间建立关系。
对体系结构视图建模
我们已经知道,视图是对系统的组织和结构的某个方面的投影,表达了对系统某个方面的关注。理论上,我们完全可以利用包元素来创建自己的体系结构视图。实际上,现在绝大部分的UML建模工具的视图结构也是使用包元素来划分其体系结构视图的。