依赖、关联、聚合和组合之间区别

在学习面向对象设计对象关系时,依赖、关联、聚合和组合这四种关系之间区别比较容易混淆。特别是后三种,仅仅是在语义上有所区别,所谓语义就是指上下文环境、特定情景等。他们在编程语言中的体现倒是基本相同的,可是基本相同并不等于彻底相同,这一点在个人前一篇博文《设计模式中类的关系》中已经有所说起,下面就来详细的论述一下在java中如何准确的体现依赖、关联、聚合和组合。 java

首先看一看书上对这四种关系的定义: 编程

  • 依赖(Dependency)关系是类与类之间的联接。依赖关系表示一个类依赖于另外一个类的定义。例如,一我的(Person)能够买车(car)和房子(House),Person类依赖于Car类和House类的定义,由于Person类引用了Car和House。与关联不一样的是,Person类里并无Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中去的。通常而言,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。
  • 关联(Association)关系是类与类之间的联接,它使一个类知道另外一个类的属性和方法。关联能够是双向的,也能够是单向的。在Java语言中,关联关系通常使用成员变量来实现。
  •  聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是总体和个体之间的关系。例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便总体和个体的关系。与关联关系同样,聚合关系也是经过实例变量实现的。可是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个表明总体,另外一个表明部分。
  •  组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中表明总体的对象负责表明部分对象的生命周期,组合关系是不能共享的。表明总体的对象须要负责保持部分对象和存活,在一些状况下将负责表明部分的对象湮灭掉。表明总体的对象能够将表明部分的对象传递给另外一个对象,由后者负责此对象的生命周期。换言之,表明部分的对象在每个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期。部分和总体的生命周期同样。

——摘自《Java面向对象编程》,做者:孙卫琴 设计模式

       以上关系的耦合度依次加强(关于耦合度的概念将在之后具体讨论,这里能够暂时理解为当一个类发生变动时,对其余类形成的影响程度,影响越小则耦合度越弱,影响越大耦合度越强)。由定义咱们已经知道,依赖关系其实是一种比较弱的关联,聚合是一种比较强的关联,而组合则是一种更强的关联,因此笼统的来区分的话,实际上这四种关系、都是关联关系。 编程语言

        依赖关系比较好区分,它是耦合度最弱的一种,在java中表现为局域变量、方法的形参,或者对静态方法的调用,以下面的例子:Driver类依赖于Car类,Driver的三个方法分别演示了依赖关系的三种不一样形式。 学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Car {
     public static void run ( ) {
         System . out . println ( "汽车在奔跑" ) ;
     }
}
 
class Driver {
     //使用形参方式发生依赖关系
     public void drive1 ( Car car ) {
         car . run ( ) ;
     }
     //使用局部变量发生依赖关系
     public void drive2 ( ) {
         Car car = new Car ( ) ;
         car . run ( ) ;
     }
     //使用静态变量发生依赖关系
     public void drive3 ( ) {
         Car . run ( ) ;
     }
}

关联关系在java中通常使用成员变量来实现,有时也用方法形参的形式实现。依然使用Driver和Car的例子,使用方法参数形式能够表示依赖关系,也能够表示关联关系,毕竟咱们没法在程序中太准确的表达语义。在本例中,使用成员变量表达这个意思:车是我本身的车,我“拥有”这个车。使用方法参数表达:车不是个人,我只是个司机,别人给我什么车我就开什么车,我使用这个车。 spa

1
2
3
4
5
6
7
8
9
10
11
12
class Driver {
     //使用成员变量形式实现关联
     Car mycar ;
     public void drive ( ) {
         mycar . run ( ) ;
     }
     . . .
     //使用方法参数形式实现关联
     public void drive ( Car car ) {
         car . run ( ) ;
     }
}

聚合关系是是一种比较强的关联关系,java中通常使用成员变量形式实现。对象之间存在着总体与部分的关系。例如上例中 .net

1
2
3
4
5
6
7
class Driver {
     //使用成员变量形式实现聚合关系
     Car mycar ;
     public void drive ( ) {
         mycar . run ( ) ;
     }
}

 

 假如给上面代码赋予以下语义:车是一辆私家车,是司机财产的一部分。则相同的代码即表示聚合关系了。聚合关系通常使用setter方法给成员变量赋值。 设计

假如赋予以下语义:车是司机的必须有的财产,要想成为一个司机必需要先有辆车,车要是没了,司机也不想活了。并且司机要是不干司机了,这个车就砸了,别人谁也别想用。那就表示组合关系了。通常来讲,为了表示组合关系,经常会使用构造方法来达到初始化的目的,例如上例中,加上一个以Car为参数的构造方法 对象

1
2
3
     public Driver ( Car car ) {
         mycar = car ;
     }

因此,关联、聚合、组合只能配合语义,结合上下文才可以判断出来,而只给出一段代码让咱们判断是关联,聚合,仍是组合关系,则是没法判断的。 blog

相关文章
相关标签/搜索