2015/03/26 - 09:25
【声明】欢迎转载,但请保留文章原始出处:http://blog.csdn.net/yelangjueqi/article/details/45529235
在面向对象的系统建模中,有3中特别重要的关系:依赖(dependency),它表示类之间的使用关系(包括精化、跟踪和绑定关系);泛化(generalization),它把一般类连接到它的特殊类;关联(associatiota),表示对象之间的结构关系。其中的每一种关系都为组合对象提供了不同的方法。
1,入门
在UML中,事物之间相互联系的方式(无论是逻辑上的还是物理上的)都被建模为关系。在面向对象的建模中,有三种重要关系:依赖、
关联和泛化。
(1),依赖(dependency):是使用关系。
(2),关联(association):是实例之间的结构关系。
(3),泛化(generalization):把一般类连接到较为特殊的类,也称为超类/子类关系或父/子关系。
这3种关系覆盖了大部分事物之间相互协作的重要方式。显然,这3种关系也能很好地映射到大多数面向对象语言所提供的连接对象方式。
UML对每种关系都提供了一种图形表示。这种表示法允许脱离具体的编程语言而对关系进行可视化,可用以强调关系的最重要的部分:关
系名、关系所连接的事物和关系的特性。
2,术语和概念
关系(relationship)是事物之间的联系。在面向对象的建模中,最重要的3种关系是依赖、泛化和关联。在图形上,把关系画成一条线
,并用不同的线区别关系的种类。
2.1,依赖(dependency)是一种使用关系,说明一个事物(如类window)使用另一个事物(如类Event)的信息和服务,但反之未必。
在图形上,把依赖画成一条有向的虚线,指向被依赖的事物。当要指明一个事物使用另一个事物时,就选用依赖。
在大多数情况下,在类与类之间用依赖指明一个类使用另一个类的操作,或者它使用其他类所定义的变量和参量,如下图,这的确是一种
使用关系,如果被使用的类发生变化,那么另一个类的操作也会受到影响。因为这个被使用的类此时可能表现出不同的接口或行为。在
UML中,也可以在很多其他的事物之间创建依赖,特别是注解和包。
注解:依赖可以带有一个名字,但很少使用,除非模型有很多依赖,并且要引用他们或作出区别。在一般情况下,用衍型区别依赖的不同
含义。
2.2,泛化(generalization)是一般事物(称为超类或父类)和该事物的较为特殊的种类(称为子类或子)之间的关系。有时也被称为"is a kind of"关系:一个事物(如类BayWindow)是更一般的事物(如window)的"一个种类"。返回意味着子类的对象可以被用在父类的对象可能出现的任何地方。反之则不然,换句话说,泛化意味着子类可以替换父类的声明。子类继承父类的特性,特别是父类的属性
和操作。通常(但不总是),子类除了具有父类的属性和操作外,还具有更多的属性和操作。若子类的一个操作的实现覆盖了父类的同样
一个操作的实现,则这种情况称为多态性。其共同之处是,两个操作必须具有相同的特征标记(相同的名字和参数)。
在图形上,把泛化画成一条带有空心三角形大箭头的有向实线,指向父类。当要表示父/子关系时,就使用泛化。
一个类可以有0个、1个或多个父类。没有父类并且最少有一个子类的类称为根类或基类;没有子类的类称为叶子类。如果一个类只有一个
父类,则说它使用了单继承;如果一个类有多个父类,则说它使用了多继承。
在大多情况下,用类或接口之间的泛化表明继承关系。在UML中,也可以在其他的类目之间创建泛化关系,比如结点关系。
2.3,关联(association)是一种结构关系,它指明一个事物的对象与另一个事物的对象间的联系。给定一个连接两个类的关联。可以从一个类的对象联系到另一个类的对象。关联的两端都连接到同一个类是合法的。这意味着,从类的给定对象可以连接到该类的其他对象。恰好连接两个类的关联叫做二元关联。尽管不太常见,但可以有连接多于两个类的关联,这种关联叫做N元关联。在图形上,把关联画成一条连接相同类或不同类的实线。当表示结构关系时,就使用关联。
PS:如何理解关联,如何使用关联?个人觉得事物的对象之间排除依赖、泛化、实现这几种关系外,又存在关系,但这种关系又不是依赖、泛化、实现的关系,那么这种关系就可以划分为关联关系。可以用关联来表示。(即实在不知道用什么关系时,就用这种排除法来确定就行啦。)
除了这种基本形式之外,还有4种应用于关联的修饰:
A,名称
关联可以有一个名称,用以描述该关系的性质。为了消除名称的歧义,可提供一个指出该名称方向的三角形,给名称一个方向。
注解:虽然关联可以有名称,但在明确给出关联的端点名的情况下通常不需要给出名称。若用多个关联连接同一个类,有必要使用关联名或关联端点名来区分它们。 若一个关联有多于一个端点是在同一个类上,有必要使用关联端点名来区分端点。若两个类之间只有一个关联,一些建模者省去了关联的名称,但为了使关联的用意清晰最好是用关联名。
B,角色
当一个类时参与了一个关联时,它就在这个关系中扮演了一个特定的角色。角色是关联中靠近它的一端的类对另一端的类呈现的面孔。可以显示地一个类在关联中所扮演的角色。 把关联端点扮演的角色称为端点名。在下图中,扮演employee角色的类person与扮演employer角色的类company相关联。
注:
a,同一个类可以在其他关联中扮演相同或不同的角色。
b,可以把属性看成类拥有的单向关联,属性名对应类的关联远端的名称。
C,关联表示了对象间的结构关系。在很多建模中问题中,说明一个关联的实例中有多少个相互连接的对象是很重要的。这个"多少"被称为关联角色的多重性,它表示一个整数的范围,指明一组相关对象的可能个数。将多重性写成一个表示取值范围的表达式,其最大值和最小值可以相同,用两个圆点把它们分开。声明了关联的一端的多重性,这说明:对于关联另一端的类的每个对象,本端的类可能有多少个对象出现。对象数目必须是在给定的范围内。可以精确地表示多重性为:一个(1)、零个或一个(0..1)、多个(0..*)、一个或多个(1..*)。可以给出它的一个整数范围(如2..5),甚至可以精确地指定多重性为一个数值(如3与3..3等价)。
如下图,每个公司对象可以雇佣一个或多个人员对象(多重性为1..*);每个人员对象受雇于0个或多个公司对象(多重性为*,它等价于0..*)。
D,聚合
两个类之间的简单关联表示了两个同等地位类之间的结构关系, 这意味着这两个类在概念上是同等级别的,一个类并不比另一个类更重要。有时要对"整体/部分"关系建模,其中一个类描述了一个较大的事物("整体"),它由较小的事物("部分")组成。这种关系称为聚合,它描述了"has a"关系,意思是整体对象拥有部分对象。 其实聚合只是一种特殊的关联, 它被表示为在整体的一端用一个空心菱形修饰的简单关联。
注:这种简单形式的聚合的含义完全是概念性的。空心菱形只是把整体和部分区别开来。这意味着简单聚合没有改变在整体和部分之间整个关联的导航含义。也与整体与部分的声明周期无关。
3,其他特征
简单而未加修饰的依赖、泛化以及带有名称、多重性和角色的关联是创建抽象时所需要的最常见的特征。事实上,对于所建的大多数模型,这三种关系的基本形式足以表达关系的最重要的语义。然而,有时需要可视化或详述其他特征,如组合聚合、导航、判别式、关联类、特殊种类的依赖和泛化。这些以及很多其他的特征都可以用UML表达。但他们都被作为高级概念处理。
依赖、泛化和关联都是定义在类这一级别上的静态事物。在UML中,通常是在类图中对这些关系进行可视化。
当开始在对象级别上建模时,特别是开始解决这些对象的动态协作时,将遇到链(它是关联的实例,描述可能发送消息的对象间的连接)。
4,绘图风格
通常,建模者选用以下两种风格之一来绘制连线:
a,用任意角度的斜线。除非需要用多条线段来避开用其他图符,否则只用一条线段。
b,要将直线画得与页边平行。除了用一条线段连接两个并排的图符的情况外,要将连线画成以直角连接的一组线段。
5,常用建模技术
5.1,对简单依赖建模
一种常见的依赖关系是两个类之间的依赖关系,其中的一个类只是使用另一个类作为它的操作参数。对这种使用关系建模,要做如下的工作:
创建一个依赖,从含有操作的类指向被该操作用作参数的类。
5.2,对单继承建模
在对系统的词汇建模中,经常会遇到在结构上或行为上与其他的类相似的类。可以把这样的每一个类建模为独立的,不相关的对象。但更好的方法是提取所有的共同特征和行为特征,并把它们提升到较为一般的类中,特殊类从中继承这些特征。
对继承关系建模,要做如下的工作:
a,给定一组类,寻找两个或两个以上的类的共同职责、属性和操作。
b,把这些共同的职责、属性和操作提升到较为一般的类中。如果需要,创建一个新类,用以分配这些元素(但要小心不要引入过多的层次)
c,画出从每个特殊类到它的较一般的父类的泛化关系,用以表示较特殊的类继承 较一般的类。
5.3,对结构关系建模
当用依赖和泛化关系建模时,可能是对表示了不同重要级别或不同抽象级别的类建模。给定两个类间的依赖,则一个类依赖另一类,但后者没有前者的任何关系。给定两个类间的泛化关系,则子类从它的父类继承,但父类没有没有任何子类所特有的信息。简而言之,依赖和泛化关系都是不对称的。
当用关联关系建模时,是在对相互相等的两个类建模。给定两个类间的关联,则这两个类以某种方式相互依赖,并且常常从两边都可以相互导航。依赖是使用关系,泛化是"is-a-kind-of"关系,而关联描述了类的对象之间相互作用的结构路径。
对结构关系建模,要做如下的工作:
a,对于每一个类,如果需要从一个类的对象到另一个类的对象导航,就要在这两个类之间说明一个关联。这是关联的数据驱动观点。
b,对于每一个类,如果一个类的对象要与另一个类的对象相互交互,而后者不作为前者的过程局部变量或者操作参数。就要在这两个类间说明一个关联。这是关联的行为驱动观点。
c,对于这样的每一个关联,要说明其多样性(特备是当多重性不为*时,其中*是默认的多重性)和角色名(特别是在有助于解释模型的的情况下)
d,如果关联中的一个类与另一端的类相比,前者在结构或者组织上是一个整体,后者看起来像它的部分,则在靠近整体的一端用一个菱形对该关联进行修饰,从而把它标记为聚合。
5.4,提示和技巧
在用UML对关系进行建模时,要遵循如下策略:
a,仅当被建模的关系不是结构关系时,才使用依赖。
b,仅当关系是"is-a-kind-of"关系时,才使用泛化。往往可以用聚合代替多继承。
c,小心不要引入循环的泛化关系
d,一般要保持泛化关系的平衡:继承的层次不要太深(大约多于5层就要想一想),也不要太宽(代之以寻找可能的中间抽象类)
e,关联主要用于对象间有结构关系的地方。不要用关联来表示暂时关系,例如过程的参数或局部变量
在用UML绘制关系时,要遵循如下策略:
a,要一致地使用平直的线或斜线。平直的线给出的可视化提示强调了相关事物之间的连接都集中到一个共同事物。在复杂的图中斜线则经常有更好的空间效果。在同一个图中使用两种线型,有助于把人们的注意力引导到不同的关系组上。
b,除非绝对必要,否则要避免连线交叉。
c,仅显示对理解特定的成组事物必不可少的关系。避免使用多于的关系(特别是多于的关联)。