您的位置:首页 > 其它

设计模式系列课程01之【依赖、关联、聚合、组合的理解】

2014-04-30 09:46 309 查看
本文转自:http://blog.csdn.net/zhengzhb/article/details/7190158

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

1、依赖(dependency)关系是类与类之间的连接,依赖关系标示一个类依赖于另外一个类的定义,比如:一个人(person)可以买车(Car)和房子(House),Person类依赖于Car类和House类的定义,因为Person类引用了Car和House,与关联不同的是,Person类里面并没有Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中去的,一般而言,依赖关系在java语言中体现为局部变量、方法的形参,或者对静态方法的调用。

2、关联(Association)关系是类与类之间的连接,它使得一个类知道另外一个类的属性和方法,关联可以是双向的也可以是单向的,在java语言中,关联关系一般使用成员变量来实现。

3、聚合(Aggregation)关系是关联关系的一种,是强的关联关系,聚合是整体和个体之间的关系,例如,汽车类与引擎类、轮胎类,以及其他的零件类之间的关系便是整体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。但是关联关系所涉及的两个类是处于同一个层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,一个代表部分。

4、组合(Composition)关系是关联关系的一种,是比聚合关系强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分对象的生命周期,组合关系是不能共享的,代表整体的对象需要负责保持部分对象和存活,在这些情况下将负责代表不烦你的对象湮灭掉,代表整体的对象可以将代表部分的对象传递给另外一个对象,由后者负责此对象的生命周期,换言之,代表部分的对象在每一个时刻只能与一个对象发生组合关系,由后者排他地负责生命周期,部分和整体的生命周期一样。

-------------------------摘自《Java面相对象编程》 作者:孙卫琴

以上关系的耦合度依次增强(关于耦合度的概念将在以后具体讨论,这里可以暂时理解为当一个类发生变更时,对其他类造成的影响程度,影响越小则耦合度越弱,影响越大则耦合度越强)。由定义我们已经知道,依赖关系实际上是一种比较弱的关联,聚合是一种比较强的关联,而3组合则是一种更强的关联,所以笼统的来区分的话,实际上这四种关系、都是关联关系。

依赖关系比较好区分,它是耦合度最弱的以中,在Java中表现为局部变量、方法的形参、或者对静态方法的调用,如下面的列子,Driver类依赖于Car类,Driver的三个方法分别演示了依赖关系的三种不同形式

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的例子,使用方法参数形式可以标示依赖关系,也可以表示关联关系毕竟我们无法在程序中太准确的表达语义,在本例中,使用成员变量表达这个意思:车是我自己的车,我拥有这个车,使用参数表达:车不是我的,我只是个司机,别人给我什么车我就开什么车,我使用这个车。
class Driver {
//使用成员变量形式实现关联
Car mycar;
public void drive(){
mycar.run();
}
...
//使用方法参数形式实现关联
public void drive(Car car){
car.run();
}
}
聚合关系是一种比较强的关联关系,Java中一般使用成员变量形式实现,对象之间存在着整体与部分的关系,比如例子中
class Driver {
//使用成员变量形式实现聚合关系
Car mycar;
public void drive(){
mycar.run();
}
}
假如给上面代码赋予如下语义:车是一辆私家车,是司机财产的一部分,则相同的代码表示聚合关系了,聚合关系一般使用setter方法给成员变量赋值。

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

public Driver(Car car){
mycar = car;
}
所以,关联、聚合、组合只能配合语义,结合上下文才能够判断出来,而只给出一段代码让我们判断是关联、聚合、还是组合关系,则是无法判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式