UML五种关系

UML五种关系


依赖关系用虚线加箭头表示,如图所示:


上图表示:Animal类依赖于Water类(动物依赖于水)。

 依赖是类的五种关系中耦合最小的一种关系。因为依赖关系在生成代码的时候,这两个关系类都不会增加属性。这种微弱的关系可以用类之间的相互了解的程度来说明。(下图为代码生成图)

                      

由上图可见生成的代码中Animal类的属性中没有增加Water类。那么Animal类如何使用Water类呢,有三种方式:

依赖关系的三种表现形式:

    Water类是全局的,则Animal类可以调用它
 

    Water类是Animal类的某个方法中的变量,则Animal类可以调用它。代码演示如下:

  PS:Animal有一个长大(GrownUp)方法,Water类作为该方法的变量来使用。
          请注意Water类的生命期,它是当Animal类的GrounUp方法被调用的时候,才被实例化。
         持有Water类的是Animal的一个方法而不是Animal,这点是最重要的。

    Water类是作为Animal类中某个方法的参数或者返回值时。代码演示如下

 

 

无用多说,Water类被Animal类的一个方法持有。生命期随着方法的执行结束而结束。

 

在依赖关系中,必须采用这三种方法之一。

 

<2>关联

关联是实线加箭头表示。表示类之间的耦合度比依赖要强。

例:水与气候是关联的,表示图如下



 

生成代码如下:





 


 

可见生成的代码中,Water类的属性中增加了Climate类。

 

关联既有单向关联又有双向关联。

单向关联:Water类和Climate类单向关联(如下图),则Water类称为源类,Climate类称为目标类。源类了解目标类的所有的属性和方法,但目标类并不了解源类的信息。

双向关联:源类和目标类相互了解彼此的信息。如将Water类和Climate类之间改为双向关联,如下图


 

 

依赖和关联的区别:

    从类的属性是否增加的角度看:

发生依赖关系的两个类都不会增加属性。其中的一个类作为另一个类的方法的参数或者返回值,或者是某个方法的变量而已。

发生关联关系的两个类,其中的一个类成为另一个类的属性,而属性是一种更为紧密的耦合,更为长久的持有关系

    从关系的生命期角度看:

依赖关系是仅当类的方法被调用时而产生,伴随着方法的结束而结束了。

关联关系是当类实例化的时候即产生,当类销毁的时候,关系结束。相比依赖讲,关联关系的生存期更长。

 

关联关系的细化

关联关系又可以细化为聚合关系和组合关系

聚合关系图:


 

组合关系图:

 


 

l      聚合和组合的区别:

由于聚合和组合都是特殊的关联关系,在生成的代码上看不出区别,都是关联的形式。那到底这两种关系如何来区分呢。

 

区分的关键有两点:

    构造函数不同

聚合关系下:雁群类(GooseGroup)和大雁类(Goose)代码如下:

 


 

组合关系下:大雁类(Goose)和翅膀类(Wings)代码如下:

 


 

这两种关系的区别在于:

①构造函数不同

    聚合类的构造函数中包含了另一个类作为参数。

雁群类(GooseGroup)的构造函数中要用到大雁(Goose)作为参数传递进来。大雁类(Goose)可以脱离雁群类而独立存在。

    组合类的构造函数中包含了另一个类的实例化。

表明大雁类在实例化之前,一定要先实例化翅膀类(Wings),这两个类紧密的耦合在一起,同生共灭。翅膀类(Wings)是不可以脱离大雁类(Goose)而独立存在

    信息的封装性不同

在聚合关系中,客户端可以同时了解雁群类和大雁类,因为他们都是独立的

而在组合关系中,客户端只认识大雁类,根本就不知道翅膀类的存在,因为翅膀类被严密的封装在大雁类中。

 

<3>泛化

泛化就是一个类继承另一个类所有的描述,并且可以根据需要对父类进行拓展,是面向对象的重要特征之一。

泛化使用一根实线加箭头,泛化关系图

 


 

泛化的用处:①实现了代码的复用

                        ②实现了多态

           

<4>实现

 主要针对接口和抽象类而言,实现接口和抽象类的类必须要实现他们的方法。

实现关系表示为:虚线加箭头,关系图如下:

 

接口只包含方法、委托或事件的签名。方法的实现是在实现接口的类中完成的。




依赖关系依赖表示两个或多个模型元素之间语义上的关系,而关联是一种结构化的关系,指一种对象和另一种对象有联系。


关联是一种结构化的关系,指一种对象和另一种对象有联系。给定有关联的两个类,可以从一个类的对象得到另一个类的对象。关联有两元关系和多元关系。两元关系是指一种一对一的关系,多元关系是一对多或多对一的关系。一般用实线连接有关联的同一个类或不同的两个类。当你想要表示结构化关系时使用关联,如果几个类元的实例之间有联系,那么这几个类元之间的语义关系即关联。关联描述了系统中对象或实例之间的离散连接。

在软件的设计初期画类图的时候经常会碰到的问题:到底这两个类是用依赖还是关联呢,关联不是也有依赖的关系吗?

的确关联也有依赖的意思,下面主要说一下他们的区别。

依赖是对象间最弱的一种关系,一个对象依赖于另一个对象是指这个对象和它之间存在短期的关系。 

 
 在这个短暂的关系中,依赖的对象通过调用被依赖对象的方法来获取它提供的服务,或者依此来配置被依赖的对象。  
关联是对象间长期的关系。在关联中,一个对象保存对另一个对象的引用,并在需要的时候调用这个对象的方法。  
  <顺便我把聚合和组合也稍微提下  
     聚合表明一个对象是一个更大的整体的一部分。这个被包含的对象可能会参与多个的聚合关系,并相对整体而对立存在。  
     组合表明一个对象是被一个更大的整体所拥有。这个被包含的对象可能不参与更多的组合关系,并且不能独立于这个整体而存在



1.  关联:连接模型元素及链接实例,用一条实线来表示;
2.  依赖:表示一个元素以某种方式依赖于另一个元素,用一条虚线加箭头来表示;
3.  聚集:表示整体与部分的关系,用一条实线加空心菱形来表示;
4.  组成:表示整体与部分的有一关系,用一条实线加实心菱形来表示;
             (关联,依赖,聚集,组成的异同见后描述)
5.  泛化(继承):表示一般与特殊的关系,用一条实线加空心箭头来表示;
6.  实现:表示类与接口的关系,用一条虚线加空心箭头来表示;
 
关联,依赖,聚集的异同:(《Java面向对象编程》一书,作者:孙卫琴 来源: [url]www.javathinker.org[/url]
在建立对象模型时,很容易把依赖、关联和聚集关系混淆。当对象A和对象B之间存在依赖、关联或聚集关系时,对象A都有可能调用对象B的方法,这是三种关系之间的相同之处,除此之外,它们有着不同的特征。
1.依赖关系的特征

对于两个相对独立的系统,当一个系统负责构造另一个系统的实例,或者依赖另一个系统的服务时,这两个系统之间主要体现为依赖关系,例如生产零件的机器和零件,机器负责构造零件对象。再例如充电电池和充电器,充电电池通过充电器来充电。再例如自行车Bicycle和打气筒Pump,自行车通过打气筒来充气。图1-39为Bicycle类与Pump类的类框图。
图1-39 Bicycle类与Pump类的依赖关系
Bicycle类和Pump类之间是依赖关系,在Bicycle类中无需定义Pump类型的变量。Bicycle类的定义如下:
public class Bicycle{
/** 给轮胎充气 */
public void expand(Pump pump){
pump.blow();
}
}

在现时生活中,通常不会为某一辆自行车配备专门的打气筒,而是在需要充气的时候,从附近某个修车棚里借个打气筒打气。在程序代码中,表现为Bicycle类的expand()方法有个Pump类型的参数。以下程序代码表示某辆自行车先后到两个修车棚里充气:
myBicycle.expand(pumpFromRepairShed1); //到第一个修车棚里充气
myBicycle.expand(pumpFromRepairShed2); //若干天后,到第二个修车棚里充气
2.关联关系的特征
对于两个相对独立的系统,当一个系统的实例与另一个系统的一些特定实例存在固定的对应关系时,这两个系统之间为关联关系。例如客户和订单,每个订单对应特定的客户,每个客户对应一些特定的订单;再例如公司和员工,每个公司对应一些特定的员工,每个员工对应一特定的公司;再例如自行车和主人,每辆自行车属于特定的主人,每个主人有特定的自行车,图1-40显示了主人和自行车的关联关系。而充电电池和充电器之间就不存在固定的对应关系,同样自行车和打气筒之间也不存在固定的对应关系。
图1-40 主人和自行车的关联关系

Person类与Bicycle类之间存在关联关系,这意味着在Person类中需要定义一个Bicycle类型的成员变量。以下是Person类的定义:
public class Person{
private Bicycle bicycle; //主人的自行车
public Bicycle getBicycle(){
return bicycle;
}
public void setBicycle(Bicycle bicycle){
this.bicycle=bicycle;
}
/** 骑自行车去上班 */
public void goToWork(){
bicycle.run();
}
}

在现时生活中,当你骑自行车去上班时,只要从家里推出自己的自行车就能上路了,不象给自行车打气那样,在需要打气时,还要四处去找修车棚。因此,在Person类的goToWork()方法中,调用自身的bicycle对象的run()方法。假如goToWork()方法采用以下的定义方式:
/** 骑自行车去上班 */
public void goToWork(Bicycle bicycle){
bicycle.run();
}
那就好比去上班前,还要先四处去借一辆自行车,然后才能去上班。

3.聚集关系的特征

当系统A被加入到系统B中,成为系统B的组成部分时,系统B和系统A之间为聚集关系。例如自行车和它的响铃、龙头、轮胎、钢圈以及刹车装置就是聚集关系,因为响铃是自行车的组成部分。而人和自行车不是聚集关系,因为人不是由自行车组成的,如果一定要研究人的组成,那么他应该由头、躯干和四肢等组成。由此可见,可以根据语义来区分关联关系和聚集关系。
聚集关系和关联关系的区别还表现在以下方面:
(1) 对于具有关联关系的两个对象,多数情况下,两者有独立的生命周期。比如自行车和他的主人,当自行车不存在了,它的主人依然存在;反之亦然。但在个别情况下,一方会制约另一方的生命周期。比如客户和订单,当客户不存在,它的订单也就失去存在的意义。
(2) 对于具有聚集关系(尤其是强聚集关系)的两个对象,整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失,部分也就随之消失。比如小王的自行车被偷了,那么自行车的所有组件也不存在了,除非小王事先碰巧把一些可拆卸的组件(比如车铃和坐垫)拆了下来。
不过,在用程序代码来表示关联关系和聚集关系时,两者比较相似。图1-41为自行车Bicycle与响铃Bell的聚集关系。
图1-41 自行车和响铃的聚集关系
以下例程1-6是Bicycle类的源程序。
例程1-6 Bicycle.java
public class Bicycle{
private Bell bell;
public Bell getBell(){
return bell;
}
public void setBell(Bell bell){
this.bell=bell;
}
/** 发出铃声 */
public void alert(){
bell.ring();
}
}
在Bicycle类中定义了Bell类型的成员变量,Bicycle类利用自身的bell成员变量来发出铃声,这和在Person类中定义了Bicycle类型的成员变量,Person类利用自身的bicycle成员变量去上班很相似。
4。组成关系的特征
组成关系是一种两个类之间的关系,其中整体类由部分类组成,部分类需要整体类才能存在,这种关系意味着销毁整体类将会同时销毁部分类


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值