在學習面向對象設計對象關係時,依賴、關聯、聚合和組合這四種關係之間區別比較容易混淆。特別是後三種,僅僅是在語義上有所區別,所謂語義就是指上下文環境、特定情景等。他們在編程語言中的體現倒是基本相同的,可是基本相同並不等於徹底相同,這一點在個人前一篇博文《設計模式中類的關係》中已經有所說起,下面就來詳細的論述一下在java中如何準確的體現依賴、關聯、聚合和組合。 java
首先看一看書上對這四種關係的定義: 編程
——摘自《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