UML圖有很多種,但是并非必須掌握所有的UML圖蝗蛙,才能完整系統(tǒng)分析和設(shè)計工作。一般說來醉鳖,在UML圖中捡硅,只要掌握類圖、用例圖盗棵、時序圖的使用壮韭,就能完成大部分的工作。也就是說纹因,掌握UML的20%喷屋,就能做80%的事情。對于程序員來說瞭恰,最頻繁使用的莫過于類圖屯曹。因此,這里我們只講解UML類圖惊畏。至于其它UML圖恶耽,請在以后的工作中參閱更多UML學(xué)習(xí)資料繼續(xù)學(xué)習(xí)。
類圖是面向?qū)ο笙到y(tǒng)建模中最常用和最重要的圖颜启,是定義其它圖的基礎(chǔ)偷俭。類圖主要是用來顯示系統(tǒng)中的類、接口以及它們之間的靜態(tài)結(jié)構(gòu)和關(guān)系的一種靜態(tài)模型缰盏。類圖中最基本的元素是類涌萤、接口淹遵。軟件設(shè)計師設(shè)計出類圖后,程序員就可以用代碼實現(xiàn)類圖中包含的內(nèi)容负溪。
類圖中具體類透揣、抽象、接口和包的表示法
UML類圖中具體類笙以、抽象類淌实、接口和包有不同的表示方法。
1)在UML類圖中表示具體類
具體類在類圖中用矩形框表示猖腕,矩形框分為三層:第一層是類名字拆祈。第二層是類的成員變量;第三層是類的方法倘感。成員變量以及方法前的訪問修飾符用符號來表示:
- “+”表示
public
放坏; - “-”表示
private
; - “#”表示
protected
老玛; - 不帶符號表示
default
淤年。
2)在UML類圖中表示抽象類
抽象類在UML類圖中同樣用矩形框表示,但是抽象類的類名以及抽象方法的名字都用斜體字表示蜡豹,如圖2所示麸粮。
3)在UML類圖中表示接口
接口在類圖中也是用矩形框表示,但是與類的表示法不同的是镜廉,接口在類圖中的第一層頂端用構(gòu)造型 <<interface>>表示弄诲,下面是接口的名字,第二層是方法娇唯,如圖3所示齐遵。此外,接口還有另一種表示法塔插,俗稱棒棒糖表示法梗摇,就是類上面的一根棒棒糖(圓圈+實線)。圓圈旁為接口名稱想许,接口方法在實現(xiàn)類中出現(xiàn)伶授。
4)在UML類圖中表示包
類和接口一般都出現(xiàn)在包中,UML類圖中包的表示形式如圖4所示伸刃。
在類圖中表示關(guān)系
類和類谎砾、類和接口、接口和接口之間存在一定關(guān)系捧颅,UML類圖中一般會有連線指明它們之間的關(guān)系景图。關(guān)系共有六種類型,分別是實現(xiàn)關(guān)系碉哑、泛化關(guān)系挚币、關(guān)聯(lián)關(guān)系亮蒋、依賴關(guān)系、聚合關(guān)系妆毕、組合關(guān)系慎玖,如圖6所示。
下面我們詳細講述這些關(guān)系笛粘,以及在UML類圖中如何表示這些關(guān)系援所。
1)實現(xiàn)關(guān)系
實現(xiàn)關(guān)系是指接口及其實現(xiàn)類之間的關(guān)系致盟。在UML類圖中律胀,實現(xiàn)關(guān)系用空心三角和虛線組成的箭頭來表示柴淘,從實現(xiàn)類指向接口,如圖1.9所示示括。在Java代碼中铺浇,實現(xiàn)關(guān)系可以直接翻譯為關(guān)鍵字 implements
。
2)泛化關(guān)系
泛化關(guān)系(Generalization)是指對象與對象之間的繼承關(guān)系垛膝。如果對象A和對象B之間的“is a”關(guān)系成立鳍侣,那么二者之間就存在繼承關(guān)系,對象B是父對象吼拥,對象A是子對象倚聚。例如,一個年薪制員工“is a”員工凿可,很顯然年薪制員工Salary對象和員工Employee對象之間存在繼承關(guān)系秉沼,Employee對象是父對象,Salary對象是子對象矿酵。
在UML類圖中,泛化關(guān)系用空心三角和實線組成的箭頭表示矗积,從子類指向父類全肮,如圖8所示。在Java代碼中棘捣,對象之間的泛化關(guān)系可以直接翻譯為關(guān)鍵字 extends
辜腺。
3)關(guān)聯(lián)關(guān)系
關(guān)聯(lián)關(guān)系(Association)是指對象和對象之間的連接,它使一個對象知道另一個對象的屬性和方法乍恐。在Java中评疗,關(guān)聯(lián)關(guān)系的代碼表現(xiàn)形式為一個對象含有另一個對象的引用。也就是說茵烈,如果一個對象的類代碼中百匆,包含有另一個對象的引用,那么這兩個對象之間就是關(guān)聯(lián)關(guān)系呜投。
關(guān)聯(lián)關(guān)系有單向關(guān)聯(lián)和雙向關(guān)聯(lián)加匈。如果兩個對象都知道(即可以調(diào)用)對方的公共屬性和操作存璃,那么二者就是雙向關(guān)聯(lián)。如果只有一個對象知道(即可以調(diào)用)另一個對象的公共屬性和操作雕拼,那么就是單向關(guān)聯(lián)纵东。大多數(shù)關(guān)聯(lián)都是單向關(guān)聯(lián),單向關(guān)聯(lián)關(guān)系更容易建立和維護啥寇,有助于尋找可重用的類偎球。
在UML圖中,雙向關(guān)聯(lián)關(guān)系用帶雙箭頭的實線或者無箭頭的實線雙線表示辑甜。單向關(guān)聯(lián)用一個帶箭頭的實線表示衰絮,箭頭指向被關(guān)聯(lián)的對象,如圖9所示栈戳。這就是導(dǎo)航性(Navigatity)岂傲。
一個對象可以持有其它對象的數(shù)組或者集合。在UML中子檀,通過放置多重性(multipicity)表達式在關(guān)聯(lián)線的末端來表示镊掖。多重性表達式可以是一個數(shù)字、一段范圍或者是它們的組合褂痰。多重性允許的表達式示例如下:
- 數(shù)字:精確的數(shù)量
-
*
或者0..*
:表示0到多個 -
0..1
:表示0或者1個亩进,在Java中經(jīng)常用一個空引用來實現(xiàn) -
1..*
:表示1到多個
關(guān)聯(lián)關(guān)系又分為依賴關(guān)聯(lián)、聚合關(guān)聯(lián)和組合關(guān)聯(lián)三種類型缩歪。
4)依賴關(guān)系
依賴(Dependency)關(guān)系是一種弱關(guān)聯(lián)關(guān)系归薛。如果對象A用到對象B,但是和B的關(guān)系不是太明顯的時候匪蝙,就可以把這種關(guān)系看作是依賴關(guān)系主籍。如果對象A依賴于對象B,則 A “use a” B逛球。比如駕駛員和汽車的關(guān)系千元,駕駛員使用汽車,二者之間就是依賴關(guān)系颤绕。
在UML類圖中幸海,依賴關(guān)系用一個帶虛線的箭頭表示,由使用方指向被使用方奥务,表示使用方對象持有被使用方對象的引用物独,如圖10所示。
依賴關(guān)系在Java中的具體代碼表現(xiàn)形式為B為A的構(gòu)造器或方法中的局部變量氯葬、方法或構(gòu)造器的參數(shù)挡篓、方法的返回值,或者A調(diào)用B的靜態(tài)方法帚称。
下面我們用代碼清單1和代碼清單2所示的Java代碼來演示對象和對象之間的依賴關(guān)系瞻凤。
代碼清單1所示的B
類定義了一個成員變量 field1
憨攒,一個普通方法 method1()
和一個靜態(tài)方法 method2()
。
//代碼清單1 B.java
public class B {
public String field1; //成員變量
public void method1() {
System.println("在類B的方法1中");
}
public static void method2() { //靜態(tài)方法
System.out.println("在類B的靜態(tài)方法2中");
}
}
代碼清單2所示的A
類依賴于B
類阀参,在A
類中定義了四個方法肝集,分別演示四種依賴形式。
/* 代碼清單2 A.java
A依賴于B
*/
public class A {
public void method1() {
//A依賴于B的第一種表現(xiàn)形式:B為A的局部變量
B b = new B();
b.method1();
}
public void method2() {
//A依賴于B的第二種表現(xiàn)形式: 調(diào)用B的靜態(tài)方法
B.method2();
}
public void method3(B b) {
//A依賴于B的第三種表現(xiàn)形式:B作為A的方法參數(shù)
String s = b.field1;
}
//A依賴于B的第四種表現(xiàn)形式:B作為A的方法的返回值
public B method4() {
return new B();
}
}
5)聚合關(guān)系與組合關(guān)系
聚合(Aggregation)是關(guān)聯(lián)關(guān)系的一種特例蛛壳,它體現(xiàn)的是整體與部分的擁有關(guān)系杏瞻,即 “has a” 的關(guān)系。此時整體與部分之間是可分離的衙荐,它們可以具有各自的生命周期捞挥,部分可以屬于多個整體對象,也可以為多個整體對象共享忧吟,所以聚合關(guān)系也常稱為共享關(guān)系砌函。例如,公司部門與員工的關(guān)系溜族,一個員工可以屬于多個部門讹俊,一個部門撤消了,員工可以轉(zhuǎn)到其它部門煌抒。
在UML圖中仍劈,聚合關(guān)系用空心菱形加實線箭頭表示,空心菱形在整體一方寡壮,箭頭指向部分一方贩疙,如圖11所示。
組合(Composition)也是關(guān)聯(lián)關(guān)系的一種特例况既,它同樣體現(xiàn)整體與部分間的包含關(guān)系这溅,即 “contains a” 的關(guān)系。但此時整體與部分是不可分的棒仍,部分也不能給其它整體共享芍躏,作為整體的對象負責(zé)部分的對象的生命周期。這種關(guān)系比聚合更強降狠,也稱為強聚合。如果A
組合B
庇楞,則A
需要知道B
的生存周期榜配,即可能A
負責(zé)生成或者釋放B
,或者A
通過某種途徑知道B
的生成和釋放吕晌。
例如蛋褥,人包含頭、軀干睛驳、四肢烙心,它們的生命周期一致膜廊。當(dāng)人出生時,頭淫茵、軀干爪瓜、四肢同時誕生。當(dāng)人死亡時匙瘪,作為人體組成部分的頭铆铆、軀干、四肢同時死亡丹喻。
在UML圖中薄货,組合關(guān)系用實心菱形加實線箭頭表示,實心菱形在整體一方碍论,箭頭指向部分一方谅猾,如圖12所示。
在Java代碼形式上鳍悠,聚合和組合關(guān)系中的部分對象是整體對象的一個成員變量税娜。但是,在實際應(yīng)用開發(fā)時贼涩,兩個對象之間的關(guān)系到底是聚合還是組合巧涧,有時候很難區(qū)別。在Java中遥倦,僅從類代碼本身是區(qū)分不了聚合和組合的谤绳。如果一定要區(qū)分,那么如果在刪除整體對象的時候袒哥,必須刪掉部分對象缩筛,那么就是組合關(guān)系,否則可能就是聚合關(guān)系堡称。從業(yè)務(wù)角度上來看瞎抛,如果作為整體的對象必須要部分對象的參與,才能完成自己的職責(zé)却紧,那么二者之間就是組合關(guān)系桐臊,否則就是聚合關(guān)系。
例如晓殊,汽車與輪胎断凶,汽車作為整體,輪胎作為部分巫俺。如果用在二手車銷售業(yè)務(wù)環(huán)境下认烁,二者之間就是聚合關(guān)系。因為輪胎作為汽車的一個組成部分,它和汽車可以分別生產(chǎn)以后裝配起來使用却嗡,但汽車可以換新輪胎舶沛,輪胎也可以卸下來給其它汽車使用。如果用在駕駛系統(tǒng)業(yè)務(wù)環(huán)境上窗价,汽車如果沒有輪胎如庭,就無法完成行駛?cè)蝿?wù),二者之間就是一個組合關(guān)系舌镶。再比如網(wǎng)上書店業(yè)務(wù)中的訂單和訂單項之間的關(guān)系柱彻,如果訂單沒有訂單項,也就無法完成訂單的業(yè)務(wù)餐胀,所以二者之間是組合關(guān)系哟楷。而購物車和商品之間的關(guān)系,因為商品的生命周期并不被購物車控制否灾,商品可以被多個購物車共享卖擅,因此,二者之間是聚合關(guān)系墨技。
文章轉(zhuǎn)自:https://zhuanlan.zhihu.com/p/109655171