?????? 對(duì)于很多剛剛接觸UML的童鞋,可能會(huì)對(duì)類之間的關(guān)聯(lián)與依賴關(guān)系不太理解,今天小菜就淺薄的講一下。
?????? 這塊的確是有點(diǎn)亂,不過小菜突然找到了一個(gè)比較好的切入點(diǎn),拿出來分享一下。
?????? 接觸過設(shè)計(jì)模式的讀者,會(huì)經(jīng)常看到這樣的場(chǎng)景:在實(shí)例化A類的時(shí)候,需要B類作為構(gòu)造方法的參數(shù),這說明A類需要持有一個(gè)B類的引用。比如代理模式、裝飾模式等,都會(huì)這樣做。例如Java中的IO流采用的就是裝飾模式,所以我們會(huì)經(jīng)常看到這樣的語句:new BufferInputStream(new FileInputStream("c:\\1.db"));
?????? 這種持有引用,就是簡(jiǎn)單的關(guān)聯(lián)關(guān)系。在代碼中表現(xiàn)為:在A類中有一個(gè) 成員變量 ,變量的類型是B類,A類中持有了B類的引用,就說明A類和B類發(fā)生了關(guān)聯(lián)關(guān)系。
?????? 用UML圖表示如下:
?????? 稍加說明,由于是A類持有B類的引用,因此關(guān)聯(lián)是從A類中發(fā)出的(由A類引起),因此箭頭要從A類指向B類。
?????? 通常情況下,這種簡(jiǎn)單的單向關(guān)聯(lián)就夠用了,但是關(guān)聯(lián)關(guān)系主要還是應(yīng)用在數(shù)據(jù)庫設(shè)計(jì)中。
?????? 在數(shù)據(jù)庫設(shè)計(jì)中,無論是一對(duì)一、一對(duì)多、多對(duì)多,都不是單向的。
?????? 從表的角度分析,它們均可以從任意一端確定另一端。就拿一對(duì)多來說,有了one端的主鍵,可以根據(jù)many端表的外鍵查出many端數(shù)據(jù);有了many端外鍵,可以根據(jù)one端表的主鍵查出one端數(shù)據(jù)。
?????? 從實(shí)體類的角度分析,同樣可以從任意一端確定另一端。還是拿一對(duì)多來說,one端的實(shí)體類會(huì)持有一個(gè)many端的引用集合,例如private Set<B> bs;,查詢到了one端,可以直接從這個(gè)集合中讀取many端;many端的實(shí)體類會(huì)持有一個(gè)one端的引用,例如private A a;,查詢到了many端,可以直接從這個(gè)引用確定每一個(gè)many端的one端。
?????? 這樣一來,就成了雙向關(guān)聯(lián),用UML畫關(guān)聯(lián)關(guān)系的時(shí)候,兩邊都要加箭頭,這樣太難看,索性就都不加了。
?????? 例如部門實(shí)體類和員工實(shí)體類的關(guān)系,就可以這樣表示:
?
?????? 由于是數(shù)據(jù)庫實(shí)體類間的關(guān)聯(lián)關(guān)系,因此還要加上數(shù)量關(guān)系,1代表one端,0..n代表many端,說明一個(gè)部門可以有多個(gè)員工,但一個(gè)員工只能屬于一個(gè)部門,通過UML圖描述了一對(duì)多。
?????? 這個(gè)才是關(guān)聯(lián)關(guān)系典型的應(yīng)用。
?????? 不得不提的是,關(guān)聯(lián)關(guān)系還可以細(xì)分為聚合和組合(二者的具體概念讀者自行搜索)。
?????? 小菜發(fā)現(xiàn)聚合、組合可以從另一個(gè)角度去理解。
?????? 先說說聚合,它是一種弱關(guān)聯(lián),大概意思就是整體和部分可以獨(dú)立存在。如果我們換個(gè)角度,可以看成是數(shù)據(jù)庫的級(jí)聯(lián)操作。
?????? 就拿小組和組員來說,刪除某個(gè)小組的時(shí)候,把該組的組員也刪除,這顯然是不科學(xué)的,因?yàn)樾〗M和組員是一種弱關(guān)聯(lián),小組可以擁有任意一個(gè)組員,一個(gè)組員也可以去任意一個(gè)小組,這個(gè)小組不存在了,可以去另一個(gè)小組,它們沒有必然的關(guān)聯(lián),可以稱為聚合。
?????? 因此,我們?cè)谠O(shè)計(jì)數(shù)據(jù)庫的時(shí)候,往往不會(huì)設(shè)置級(jí)聯(lián)刪除,也就是說,刪除小組時(shí)不會(huì)刪除組員。
?????? UML圖表示如下:
?????? 空心菱形表示聚合,指向one端。
?????? 再說說組合,組合是一種強(qiáng)關(guān)聯(lián),大概意思是整體和部分不可分割,不能獨(dú)立存在。同樣從級(jí)聯(lián)操作理解。
?????? 就拿學(xué)生和學(xué)生證來說,假如某個(gè)學(xué)生退學(xué),不再屬于這個(gè)學(xué)校,那么可以考慮將該學(xué)生信息刪除,刪除的時(shí)候,學(xué)生對(duì)應(yīng)的學(xué)生證信息也會(huì)被刪除,在此處可以加級(jí)聯(lián)刪除。因?yàn)閷W(xué)生證屬于某個(gè)學(xué)生專有的信息,學(xué)生不存在了,學(xué)生證又不能讓他人使用,因此是一種強(qiáng)關(guān)聯(lián),可以稱為組合。
?????? UML圖表示如下:
?????? 最后要談的是依賴關(guān)系。
?????? 假如A類的某個(gè)方法中,使用了B類,那么就說A類依賴于B類,它們是依賴關(guān)系。
?????? A類的某個(gè)方法使用B類,可能是方法的參數(shù)是B類,也可能是在方法中獲得了一個(gè)B類實(shí)例。但無論是哪種情況,B類在A類中都是以 局部變量 的形式存在的。
?????? 因此,A類中有B類型的局部變量,就說A類依賴于B類。
?????? UML圖表示如下:
?????? 虛線箭頭表示依賴,箭頭指向被依賴的類。
?????? 綜上,有一個(gè)簡(jiǎn)單的判斷原則:某個(gè)類以 成員變量 的形式出現(xiàn)在另一個(gè)類中,二者是關(guān)聯(lián)關(guān)系;某個(gè)類以 局部變量 的形式出現(xiàn)在另一個(gè)類中,二者是依賴關(guān)系。
?????? 注意: 本文為了方便講解,一直是拿類當(dāng)例子,這并不是一種好的設(shè)計(jì)思維。實(shí)際開發(fā)中,為了更好的實(shí)現(xiàn)"開-閉原則",一般都是定義接口,依賴于接口,依賴于抽象,而不是根據(jù)具體編程,希望讀者不要被小菜誤導(dǎo)!!
?????? 小菜水平有限,就先談到這,文章如有不當(dāng)之處請(qǐng)見諒,歡迎與我交流!
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
