常见UML图

UML中的图有:

一、用况图

        用况图展示了用况之间以及同用况与参与者之间是怎样相互联系的。用况图用于对系统、子系统或类的行为进行可视化,使用户能够理解如何使用这些元素,并使开发者能够实现这些元素。用况图呈现了一些参与者和一些用况,以及它们之间的关系。主要用于对系统(子系统)的功能行为进行建模。使用用况图可以:

  • 通过表示在语境中参与者如何与系统交互,使得系统、子系统和类对于用户和开发者易于探讨和理解。
  • 易于对需求规范化
  • 有利于进行OOA
  • 有助于发现主动对象
  • 对系统测试来说,产生测试用例。
  • 有助于人机界面设计

    在图形上,用况图是一幅由一组参与者、一组用况以及这些元素之间的关系组成的图。这些关系是参与者和用况之间的关联、参与者之间的泛化,以及用况之间的泛化、扩展和包含。可以选择把一些用况用一个矩形围起来,用来表示系统、子系统或“类”的边界。用况图可以包含注解和约束。 

1、概念说明

1.系统相关概念

系统:是由“用户”使用的软件,以及所有与其相关的硬件。指被开发的计算机软硬件系统,不是指现实世界的系统。

系统边界:一个系统所包含的所有系统成分与系统以外各种事物的分界线。

系统成分:在OOA和OOD中定义,在编程时加以实现的系统元素——对象

2.参与者

        简言之,参与者是在系统之外的与系统进行交互的任何事物。一个参与者定义了用况的使用者在与这些用况交互时所扮演的一组功能高内聚的角色:

  • 参与者可以发出对系统服务的请求。
  • 所有参与者的请求/响应的完全集构成了可以觉察到的系统的问题域边界。
  • 一个参与者的一个实例代表以一种特定的方式与系统进行的单独的交互。
  • 尽管在模型中使用参与者,但参与者实际上并不是系统的一部分。它们存在于系统之外。 
  • 如果一组参与者具有共同的性质,可以把这些性质抽取出来放在另一个参与者中,它们再从中继承,把这种关系称为参与者之间的泛化关系。 从参与者A到参与者B之间的泛化关系是指,A的实例能与和B实例进行通讯的用况实例进行通信。

如何发现参与者?

  • 从人员角度

系统的直接使用者

直接为系统服务的人员

  • 从设备角度

与系统直接相联的设备

为系统提供信息

在系统控制下运行

  • 从外部系统角度

上级系统

子系统

其它系统

3.用况

        用况是对参与者使用系统的一项功能时所进行的交互过程的描述。 几点说明:

(1)一个用况描述参与者对一项或几项系统功能的使用情况。而且只有当外部的参与者与该系统或类目进行交互时,该功能才发挥作用。 

(2)用况中描述的行为实际上是系统级的。在用况内所描述的交互中的动作应该是详细的,准则是对用况的理解不产生歧义即可;若描述得过于综合,则不易认识清楚系统的功能。

(3)陈述参与者和系统在交互过程中双方所做的事。而且描述彼此为对方直接地做什么事,不描述怎么做,内部细节不要在其中描述。 

(4)用况既表达了系统的功能需求,也表达了系统的功能划分。 

(5)描述应力求准确、清晰,允许概括,但不要把双方的行为混在一起。

(6)系统执行该动作序列来为参与者产生一个可观察的结果值。

(7)用况描述的是一个参与者所使用的一项系统功能,该项功能应该相对完整。这就要求一个用况描述的功能,即不能过大以至于包含过多的内容,也不能过小以至于仅包含完成一项功能的若干步骤。

(8)用况描述中的一个步骤应该描述且仅描述参与者或系统要完成的一件事情。 

(9)可以使用类图、活动图等对用况进行详细说明。

1.用况间的关系

        在下述情况下,就需要考虑产生新的用况,并在用况间建立关系:

  •  在一个用况中存在着几处重复使用的动作序列;
  •  在几个用况中存在着重复使用的动作序列;
  •  一个用况中的主要动作序列或分支动作序列过于冗长或复杂,而且分离它们有助于管理和理解。

1.扩展关系

        按基用况中指定的扩展条件,把扩展用况的行为插入到由基用况中的扩展点定义的位置。 

       通过敞开的虚线箭头表示用况之间的扩展关系,该箭头从提供扩展的用况指向基用况。这个箭头用关键字<<extend>>标记。可以在这个关键字附近表示这个关系的条件。

2.包含关系

        基用况在它内部说明的某一(些)位置上显式地使用供应者用况的行为的结果。

        通过一个敞开的虚线箭头表示用况之间的包含关系,该箭头从基用况指向被包含的用况。这个箭头用关键字<<include>>标记。

 

3.泛化关系

        用况之间的泛化关系就像类之间的泛化关系一样。子用况继承父用况的行为和含义;子用况还可以增加或覆盖父用况的行为;子用况可以出现在父用况出现的任何位置(父和子均有具体的实例)。

        用一个指向父用况的带有封闭的空心箭头的实线来表示用况之间的泛化关系。

2.捕获用况

1)利用参与者捕获用况 

对所有的参与者(把自己作为参与者),提问下列问题:

  • 每个参与者的主要任务是什么?
  • 为了达到某种目的,它们参加什么活动?该参与者是否将读写系统的任何信息?参与者是否该把系统外部的变化通知系统?参与者是否希望系统把预料之外的变化通知自己?
  • 在交互过程中,它们是怎样使用系统的服务来完成它们的任务以达到目的?
  • 它们参加了什么在本质上是不同的过程?
  • 是什么事件引起了与系统进行交互的序列?

   能完成特定功能的每一项活动明确地是一个用况。这些参与者参与的活动,通常会导致其它用况。 

2)从系统功能角度捕获用况

用于本步骤的一些简单的指导如下:

  •  一个用况描述一项功能,这项功能不能过大。例如,把一个企业信息管理系统粗略地分为生产管理、供销管理、财务管理和人事管理等几大方面的功能,就显得粒度太大了,应该再进行细化。
  • 全面地认识和定义每一个用况,要点是以穷举的方式考虑每一个参与者与系统的交互情况,看看每个参与者要求系统提供什么功能,以及参与者的每一项输入信息将要求系统作出什么反映,进行什么处理。
  • 以穷举的方式检查用户对系统的功能需求是否能在各个用况中体现出来。
  • 一个用况应该是一个完整的任务,通常应该在一个相对短的时间段内完成。如果一个用况的各部分被分配在不同的时间段,尤其被不同的参与者执行,最好还是将各部分作为单独的用况对待。
  • 考虑对例外情况的处理。针对用况描述的基本流,要详尽地考虑各种其他的情况 

3)使用场景技术

       如果不能顺利地确定一个用况的描述,可尽早使用人们熟知的“角色扮演”技术。 

2、使用案例

        很多软件系统在一开始都需要登录,若用户登录成功,则可进入系统。如下以一个研究生学籍管理系统为例,描述四种登录方法。为了简化起见,假设此处仅描述登录、选课和查看学分这3项功能。 

方案一:

        由于选课和查看学分都需要登录,故专门设立一个“登录”用况。若登录成功,则可以进行选课,也可以进行查看学分。

 分析:

        该方法的缺点是,必须要了解系统的所有其它模块,才能描述清楚“登录”用况。向系统增加新用况时,也要修改登录用况。此外,从维护的角度看,有时会忘记对“登录”用况进行修改。 

方案二:

        让所有的相关用况都包含登录用况。

分析: 

        这个方法中的“登录”用况仅描述有关登录的信息,研究生执行系统的每项功能都要先登录。其缺点为,对研究生要进行多次验证。 

方案三:

  使用扩展,设计系统登录。

分析:

        该方法与方法一相比,对“登录”用况的描述要清楚一些。在增加新用况时,仅在登录用况中添加扩展点即可。 

方案四:

  登录用况完全独立于其它用况 。

分析:

        若使用该方法,必须要在“选课”用况和“查看学分”用况中指定前置条件:只有在登录成功后才能执行自己。

二、类图

        在模型中用类符号来表示一个类,它代表属于该类的全部对象实例。

 

说明:最上面的那个名称栏包含类名;中间的分栏包含属性列表;最下面的分栏包含操作列表。每个属性和操作各占一行。

属性/操作表示格式:[可见性] 属性名/操作名[‘:’类型][‘ =’初始值]

 其中可见性分为+(公有的)、#(受保护的)或 -(私有的)、 ~(包,只有在同一包中声明的类能够使用这一属性)。 

1、类(及其对象)之间的关系

1.泛化(一般-特殊)

        泛化(generalization)是较特殊的类和较一般的类之间的直接关系(继承关系),其中较一般的类具有较特殊的类的共同性质,较特殊的类继承较一般的类的性质,且还具有自己的性质,或额外的关联,较特殊的类的对象是较一般的类的对象的子集。

         如果类A具有类B的全部属性和全部操作,而且具有自己特有的某些属性或操作,则A叫做B的特殊类,B叫做A的一般类。其表示方法为:

 2.关联(实例连接)

1.基本介绍

        对象之间的静态联系是指,最终可通过对象属性来表示的一个对象对另一个对象的联系。用链* (link)表示类对象之间的静态联系。对象之间的动态联系是指,对象之间在行为(操作)上的依赖关系。 用关联* (association)表示类之间的静态联系。如果类的对象之间通过属性有连接关系,那么这些类之间的语义关系就是关联(association)。 其表示为:

2.常见概念

1) 多重性

  • 多重性是非负整数开集的一个子集。
  • 另一端上的多重性是指,对于本端的一个对象,需要另一端对象的个数。
  • 把多重性规约表示成由用逗号分开的整数间隔序列组成的字符串,间隔代表整数的范围(可能无限),其格式为:下限..上限

其中的下限和上限都是文字整型值,说明从下限到上限的整数闭区间。此外星号(*)可以用于上限,表明不限制上限。 如果多重性规约由单个的(*)构成,那么它就表明了无穷的非负正整数的范围,也即它等价于0..*。

2) 关联类 (association class)

  • 具有关联和类的特征的建模元素。关联类既可以被看作是具有类的性质的关联,也可以被看作为具有关联性质的类。
  • 如果在具有关联关系的类中,存在着一个属性放在哪个类中都不合适的情况,就考虑使用关联类。 

如下:

3) N元关联

        N元关联是三个或三个以上类之间的一个关联。可以规约N元关联的多重性,但与二元关联的多重性相比,并不那样明显。在一个角色上的多重性,当该N元关联中的其它N-1个值被确定时,表示该关联潜在的实例元组的数目。

        通过一个大的菱形(指的是比在路径上的终端符大)表示一个N元关联,这个菱形有很多与各参与的类相连接路径。关联的名字(如果有的话)显示在菱形附近。同二元关联一样,角色修饰可以显示在每一个路径上。

        可以用虚线把关联类符号与菱形连接起来,表示具有属性、操作或关联的N元关联。 

它也可以转换为二元关系如下:

 4) 限定关联

       在使用关联时,一种常见的用法是查找。给定关联一端类中的一个对象,按照另一端类的对象的特点,查找其中的对象或对象集时,就需要使用限定关联。 

       例如,通常产品订单由若干定单行和一些其它描述信息组成, 使用限定关联描述产品订单、订单行以及它们之间的关系。 

3.聚合(整体-部分)

        用于描述系统中各类对象之间的组成关系,通过它可以看出某个类的对象,以另外一些类的对象作为其组成部分。聚合(aggregation)是关联的一种特殊形式,表示整体和部分之间的“整体-部分”关系。聚集 (aggregate)是聚合关系中作为“整体”的类,而把作为“部分”的类称为 成分或部分。

        类与类之间的聚合关系指的是,一个类的对象实例,以另一个类的对象实例作为其组成部分, 是种“a part of”或“has a” ;也可理解为,一个类定义引用另一个类定义。

        组合是聚合的一种形式,其部分和整体之间具有很强的“属于”关系,整体类的对象管理部分类的对象, 决定部分类的对象何时属于它,何时不属于它。部分可以先于整体消亡。这种聚集末端的多重性不能超过1。组合对象是组合类的实例。 

举例说明:

4.依赖

       一个依赖规约了两个或多个模型元素(或两个模型元素集合)之间的一种语义关系,对目标元素的改变可能需要改变该依赖中的源元素。如:

        仅当被建模的关系不是结构关系时,才使用依赖。关联主要用于类间有结构关系的地方。把依赖表示为两个模型元素之间的虚线箭头。在箭头尾部的模型元素(客户)依赖箭头头部的模型元素(提供者)。箭头可以用放在双尖括号内的字符串标识。

2、接口

        平时在定义类时,可见性为公共的操作就构成了一组外部可访问的操作,为其它的类提供服务。把这组操作组织起来,作为该类的一个或几个接口,说该类提供了对其接口的实现。还有一种接口是纯粹的,就象Java中的接口那样。这种接口仅具有操作说明,没有实现,它作为实现它和使用它的类的桥梁。在UML中,把一个接口定义为一个类、构件或子系统的对外可见的一组操作的描述符。它定义了类、构件或子系统对外提供的服务。接口定义了一个契约,在接口两端的遵循该接口的任何类、构件或子系统可以独立变更,但必须忠实地履行这个契约。 

 

        抽象类可以作为接口,但严格地讲,二者是有区别的,是不相同的建模元素。抽象类可以含有属性和一些具体操作,而接口没有属性,且不能在其中定义任何具体操作的方法 。接口更像一个其所有的操作都是抽象的抽象类。

三、顺序图

        顺序图(Sequence Diagram)是一种详细表示对象之间以及对象与系统外部的参与者之间动态联系(交互)的图形文档。顺序图详细而直观地表现了一组相互协作的对象在执行一个(或少量几个)用况时的行为依赖关系,以及操作和消息的时序关系。它可以:

  • 帮助分析员对照检查每个用况中描述的用户需求,是否已经落实到一些对象中去实现。提醒分析员去补充遗漏的对象类或操作。
  • 帮助分析员发现哪些对象是主动对象
  • 通过对一个特定的对象群体的动态方面建模,深刻地理解对象之间的交互。 

 

 1、重要概念

1.对象生命线

        把对象表示成称之为“生命线”的垂直虚线。生命线代表一个对象在特定时间内的存在。如果对象在图中所示的时间段内被创建或者销毁,那么它的生命线就在适当的点开始或结束。否则,生命线应当从图的顶部一直延续到底部。

     在生命线的顶部画对象符号。如果一个对象在图中所规定的时间段被创建,那么就把创建对象的箭头的头部画在对象符号上。如果对象在图中被销毁,那么用一个大的“X” 标记它,该标记或者放在引起销毁的箭头处,或者放在从被销毁的对象最终返回的箭头处。

     在图的顶部(第一个箭头之上)放置在转换开始时就存在的对象,而在整个转换完成时仍然存在的对象的生命线,要延伸超出最后一个箭头。

  生命线可以分裂成两条或更多条并发的生命线,以表示条件性。这样的每一个生命线对应于通讯中的一个条件分支。生命线可以在某个后续点处合并。  

2.执行规约

        执行规约表示一个对象直接或者通过从属例程执行一个行为的时期。它既表示了行为执行的持续时间,也表示了活动和它的调用者之间的控制关系。

     用一个窄长的矩形表示执行规约,矩形顶端和它的开始时刻对齐,末端和它的结束时刻对齐。

     在程序的控制流中,执行规约符号的顶端画在进入的箭头的尖端(开始该动作的那个箭头),底端画在返回的箭头的尾部。

    当一个对象处于执行规约期时,该对象能够响应或发送消息,执行对象或活动。当一个对象不处于执行规约期时,该对象不做什么事情,但它是存在的,等待新的消息执行规约它。

3.消息

      消息是对象之间的通讯的规格说明,这样的通讯用于传输将发生的活动所需要的信息。它即包含了控制信息(如调用)也包含了所使用的数据的规格说明。 一个消息会调用另一个对象的操作,调用本对象的操作,向另一个对象发送一个信号,创建或者撤消一个对象(可以自己销毁自己),还可能向调用者返回一个结果。

       把消息表示为从一个对象生命线到另一个对象生命线的一个水平实线箭头,即从源对象指向目标对象,以触发目标对象中的特定操作。对于对象到自身的消息,箭头就从同一个对象符号开始和结束。用消息(操作或信号)的名字及其参数值或者参数表达式标示箭头。

消息表示为:

消息返回表示为:

同步消息:一般把它用于普通的过程调用。在外层控制恢复之前,要完成整个嵌套序列。通常把它用于普通的过程调用。 若在一个主动对象发送信号并等待完成一个嵌套的行为序列才继续时,也可以把它用于并发的主动对象。 

异步消息:用它表示异步通讯,也即发送者发出消息后,立即继续执行中的下一步,不进行等待。

4.接口

        从发送方到接受方的请求。

消息:包括预期操作信息和完成操作所需要的数据,也即包含了控制信息也包含了数据。发送方构造消息、送到通讯系统;接受方从通讯系统取消息、解析消息、处理消息。

接口:定义提供服务的一组操作,要处理的数据也通过接口传输。发送方产生调用、发出调用;接受方接收调用、执行操作。

比较:接口定义严格且可视,消息需解析。

5.信号

        对象之间的异步传送的消息的规格说明。信号名 ‘(‘用逗号分隔的参数列表‘)’从一个对象可以向另一个对象或对象的集合发送信号。例如消息广播。发送者在发送信号时,要实例化其参数。对于接收者来说,它收到的是一个事件。

        在类图中,在类符号上用关键字<<signal>>声明信号。把参数说明为属性。信号没有操作。在类的描述模板中,要指定所能接收的信号。通常用信号对异常情况建模。

 

2、顺序图中的结构化控制

         序列性的消息能很好地说明单一的线性的序列,但是我们通常需要展示条件和循环。有时候我们想要展示多个序列的并行执行。在顺序图中用结构化控制操作符能展示这种高层控制。为了表示顺序图的边界,可以把顺序图用一个封闭的矩形包围起来,并在矩形的左上角放一个小五边形。在这个小五边形内先写上sd,再后面写出图的名字。对每个子顺序图加上一个矩形区域作为外框,再在其左上角放一个小五边形,在这个小五边形内写上用来表明控制操作符的类型的文字。 常见标签有:

  • 可选执行  标签是opt

        如果控制进入该操作符标识的交互区域时监护条件成立,那么执行该交互区域。监护条件是一个用方括号括起来的布尔表达式,它要出现在交互区域内部第一条生命线的顶端,在其中可以引用该对象的属性。 

  • 条件执行  标签为 alt。

        用水平虚线把交互区域分割成几个分区,每个分区表示一个条件分支并有一个监护条件。如果一个分区的监护条件为真,就执行这个分区,但最多只能执行一个分区。如果有多于一个监护条件为真,那么选择哪个分区是不确定的。若没有应对措施,在模型中要避免这种情况。如果所有的监护条件都不为真,那么控制流将跨过这个交互区域而继续执行。其中的一个分区可以用特殊的监护条件[else],这意味着如果其他所有区域的监护条件都为假,就执行该分区。 

  • 并行执行  标签是 par。

        用水平虚线把交互区域分割为几个分区。每个分区表示一个并发计算。当控制进入交互区域时并发地执行所有的分区;在并行分区都执行完后,那么该并行操作符标识的交互区域也就执行完毕。每个分区内的消息是顺序执行的。需要指出的是,并发并不总是意味着物理上的同时执行。并发其实是说两个动作没有协作关系,而且可按任意次序发生。如果它们确实是独立的动作,那么它们还可以交叠。 

  • 循环(迭代)执行  标签是 loop。

        在交互区域内的顶端给出一个监护条件。只要在每次迭代之前监护条件成立,那么循环主体就会重复执行。一旦在交互区域顶部的监护条件为假,控制就会跳出该交互区域。 

案例:

解释:

        用户启动这个序列。第一个操作符是循环操作符,圆括号内的数字(1,3)表示循环执行的最少次数和最多次数。因为最少是一次,所以在检测条件之前主体至少执行一次。在循环内,用户输入密码,系统验证它。只要密码不正确,那么该循环就会继续。但是,如果超过了三次,那么无论如何循环都会结束。

        下一个操作符是可选操作符。如果密码是正确的,那么就执行这个操作符的主体;否则就跳过该顺序图后面的部分。这个可选操作符的主体内还包括了一个并行操作符。正如图中所表明的,操作符可以嵌套。

四、状态机图

        状态转换图(简称为状态图),通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为。此外,状态图还指明了作为特定事件的结果系统将做哪些动作(例如,处理数据)。

 1、重要概念

1.状态

        状态是任何可以被观察到的系统行为模式,一个状态代表系统的一种行为模式。状态规定了系统对事件的响应方式。系统对事件的响应,既可以是做一个(或一系列)动作,也可以是仅仅改变系统本身的状态,还可以是既改变状态又做动作。一张状态图中只能有一个初态,而终态则可以有0至多个。在实际系统中,无法建立全系统的状态图。

2.事件

        事件是在某个特定时刻发生的事情,它是对引起系统做动作或(和)从一个状态转换到另一个状态的外界事件的抽象。例如,内部时钟表明某个规定的时间段已经过去,用户移动或点击鼠标等都是事件。简而言之,事件就是引起系统做动作或(和)转换状态的控制信息。在OO中,事件是对一个可观察的事情的规格说明,这种事情的发生可以引发状态的转换。事件可以分为多种:信号事件、调用事件、时间事件、改变事件

1、举例

1.绘制一个状态图,它能分析如下格式的字符流:‘<’标记串‘>’字母串;如deFC<ejb-name>Account;

2.为简易微波炉(只有一个按钮)建模

五、通信图

        通信图表示围绕着对象角色以及对象角色之间的链所组织的交互。通信图是一种强调发送和接收消息的对象结构组织的交互图,展示围绕对象以及它们之间的连接器而组织的交互。连接器是由关联实例化的链以及通过过程参数、局部变量或全局变量而产生的对象之间的临时连接。 通信图由对象(参与者) 、连接器以及连接器上的消息构成。这些概念及表示法与前述中的都完全相同。与顺序图不同:

  • 通信图表示扮演不同角色的对象之间的关系。
  • 通信图不表示作为单独维度的时间,所以交互的顺序和并发进程必须用顺序数决定。
  • 顺序图表示执行消息的显式顺序,最好用于描述实时系统和复杂的场景。

        为表示一个消息的时间顺序,可以给消息加一个数字前缀(从1号消息开始),在控制流中,每个新的消息的顺序号单调增加(如2,3等等)。为了显示嵌套,可使用带小数点的号码(1表示第一个消息;1.1表示嵌套在消息1中的第一个消息;1.2表示嵌套在消息1中的第二个消息;等等)。嵌套可为任意深度。要注意的是,沿同一个链,可以显示多个消息(可能发自不同的方向),并且每个消息都有唯一的一个顺序号。 顺序图和通信图在语义上是等价的,它们可以从一种形式的图转换为另一种。

六、活动图

        活动图可用于对业务过程和操作的算法建模,活动图显示从活动到活动的流。活动可由动作和其他活动组成,最底层的活动是由动作执行的。在活动图中,动作和活动均具有图形表示法,且是一样的。

1、控制流

      当动作或活动结束时,马上进入下一个动作或活动。一系列的动作和活动的执行构成了一个控制流。在图形上,用一个箭头表示从一个动作或活动到下一个动作或活动的转移 

控制流也可以是并发的。用同步条表示并发控制流的分岔和汇合。 

 2、对象流 

 3、泳道

        在对业务过程建模时,可以把活动或动作分成组,每组由特定的履行者来执行。履行者可为人员、组织或其他业务实体。把每个组分别称为一个泳道。 

七、包图

        对一个较为复杂的系统建模,要使用大量的模型元素,这时就必要把这些元素分组进行组织。这样把在语义上接近且倾向于一起变化的模型组织在一起,不但控制模型的复杂度,有助于理解,而且也有助于按组控制元素的可见性。包是对模型元素分组的机制。使用包的最常见目的是把建模元素组织成为组,作为一个集合进行命名和处理。包可以拥有类、接口、构件、节点、用况和图,甚至可以是其它包。拥有是一种组成关系,这意味着被拥有的元素被声明在包中。如果包被撤消了,元素也要被撤消。  一个元素只能被一个包所拥有。设计良好的包,把在语义上接近并倾向于一起变化的元素组织在一起。因此结构良好的包是松耦合、高内聚的,而且对其内容的访问具有严密的控制。 

 1、基本事项

1.包的层次性

        因为包中还可以有包,这样包之间可以有一个层次,且在组织结构上是一棵严格的树。在实际使用中,最好要避免过深地嵌套包,一般两、三层即可。对过多的嵌套,要用“引入依赖”来组织包。

2.对包中元素的命名

        一个包形成了一个命名空间,这意味着在一个包的语境中同一种元素的名字必须是唯一的。例如,同一个包不能拥有两个名为Queue的类,但在P1包中可以有一个名为Queue的类,而在P2包中又有另一个(不同的)名为Queue的类。实际上,类P1::Queue和类P2::Queue是不同的类,这可以由各自的路径名区别开来。如果一个包位于另一个包中,外层的包可作为里层包的前缀。例如,在包Vision中有一个名为Camera的类,而包Vision又在包Sensor中。类Camera的全名为Sensor::Vision::camera。

3.包中元素的可见性

        一个包中的元素在包外的可见性,通过在元素名字前加上一个可见性符号来指示。模型元素的可见性可为+(公共的)、-(私有的)、 #(受保护的) 或~(包范围的),它们的含义为:

+:标有“+”号的模型元素对所有的引入包以及它们的后代是可见的。包的各公共部分一同构成包的接口。

-:标有“-”号的模型元素只对包内的元素是可见的。

#:标有“#”号的模型元素只对那些与包含这些元素的包有泛化关系的子包是可见的。

~:标有“#”号的模型元素只对在同一包内声明的其他元素是可见的。

4.包的用处

     1、组织相关元素,以便于管理和便于复用。包是一个命名空间,外部使用要加限定名。

     2、包引入放松了限制。被引入的元素与引入包中的元素可以进行关联,或建立泛化关系。

     3、便于组合可复用的元建模特征,以创建扩展的建模语言。也即把被合并包的特征结合到合并包,以定义新的语言。

5.如何划分包

  • 识别低层包

每个具有泛化关系或聚合关系的元素位于一个包

关联密集的类划分到一个包

独立的类暂时作为一个包

  • 合并或组织包

如果低层包数量过多,则把它们合并,或用高层包组织它们。

若低层包之间在概念上接近或具有较强的相关性,从作用上属于某项大的功能,在图上有较强的耦合性,或在分布上处于同一台处理机,则考虑把它们合并,或用高层包组织它们。

建议每个包有7±2个内层成分。——在一张A4纸上表达不清楚时就划分包(Martin Fowler)

2、包间的关系

        包之间不但可以具有拥有关系,包之间也可以具有引入关系、访问关系或泛化关系。

  • 引入依赖:是两个包之间的一种许可依赖关系,一个包中的可见性为公有的模型元素,可以在指定的包(包括嵌套在该包中的子包)中被引用,相当于把提供者包的内容附加到客户包的公共命名空间中,而不必对名称进行限制。把引入依赖绘制成带有箭头的虚线,其上标有串<<import>>。
  • 访问依赖:是两个包之间的一种许可依赖关系,一个包中的可见性为公有的模型元素,可以在指定的包(包括嵌套在该包中的子包)中被引用,相当于把提供者包的内容附加到客户包的私有命名空间中,而不必对名称进行限制。把访问依赖绘制成带有箭头的虚线,其上标有串<<access>>。
  • 泛化关系:与类间的泛化很类似,即特殊包可以继承一般包中的可见性为公共的或受保护的元素,而且在特殊包中还可以有自己的元素,自己的元素可以覆盖继承来的元素。 

猜你喜欢

转载自blog.csdn.net/qq_22172133/article/details/82119727