UML圖有很多種遮精,但是并非必須掌握所有的UML圖居夹,才能完整系統(tǒng)分析和設計工作。一般說來本冲,在UML圖中准脂,只要掌握類圖、用例圖檬洞、時序圖的使用狸膏,就能完成大部分的工作。也就是說添怔,掌握UML的20%湾戳,就能做80%的事情闷板。對于程序員來說,最頻繁使用的莫過于類圖院塞。因此遮晚,這里我們只講解UML類圖。至于其它UML圖拦止,請在以后的工作中參閱更多UML學習資料繼續(xù)學習县遣。
類圖是面向?qū)ο笙到y(tǒng)建模中最常用和最重要的圖,是定義其它圖的基礎汹族。類圖主要是用來顯示系統(tǒng)中的類萧求、接口以及它們之間的靜態(tài)結(jié)構(gòu)和關系的一種靜態(tài)模型。類圖中最基本的元素是類、接口。軟件設計師設計出類圖后血淌,程序員就可以用代碼實現(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所示。
在類圖中表示關系
類和類植酥、類和接口镀岛、接口和接口之間存在一定關系,UML類圖中一般會有連線指明它們之間的關系友驮。關系共有六種類型漂羊,分別是實現(xiàn)關系、泛化關系卸留、關聯(lián)關系走越、依賴關系、聚合關系耻瑟、組合關系旨指,如圖6所示。
下面我們詳細講述這些關系喳整,以及在UML類圖中如何表示這些關系淤毛。
1)實現(xiàn)關系
實現(xiàn)關系是指接口及其實現(xiàn)類之間的關系。在UML類圖中算柳,實現(xiàn)關系用空心三角和虛線組成的箭頭來表示低淡,從實現(xiàn)類指向接口,如圖1.9所示瞬项。在Java代碼中蔗蹋,實現(xiàn)關系可以直接翻譯為關鍵字 implements
。
2)泛化關系
泛化關系(Generalization)是指對象與對象之間的繼承關系囱淋。如果對象A和對象B之間的“is a”關系成立猪杭,那么二者之間就存在繼承關系,對象B是父對象妥衣,對象A是子對象皂吮。例如,一個年薪制員工“is a”員工税手,很顯然年薪制員工Salary對象和員工Employee對象之間存在繼承關系蜂筹,Employee對象是父對象,Salary對象是子對象芦倒。
在UML類圖中艺挪,泛化關系用空心三角和實線組成的箭頭表示,從子類指向父類兵扬,如圖8所示麻裳。在Java代碼中口蝠,對象之間的泛化關系可以直接翻譯為關鍵字 extends
。
3)關聯(lián)關系
關聯(lián)關系(Association)是指對象和對象之間的連接津坑,它使一個對象知道另一個對象的屬性和方法妙蔗。在Java中,關聯(lián)關系的代碼表現(xiàn)形式為一個對象含有另一個對象的引用疆瑰。也就是說眉反,如果一個對象的類代碼中,包含有另一個對象的引用乃摹,那么這兩個對象之間就是關聯(lián)關系禁漓。
關聯(lián)關系有單向關聯(lián)和雙向關聯(lián)。如果兩個對象都知道(即可以調(diào)用)對方的公共屬性和操作孵睬,那么二者就是雙向關聯(lián)播歼。如果只有一個對象知道(即可以調(diào)用)另一個對象的公共屬性和操作,那么就是單向關聯(lián)掰读。大多數(shù)關聯(lián)都是單向關聯(lián)秘狞,單向關聯(lián)關系更容易建立和維護,有助于尋找可重用的類蹈集。
在UML圖中烁试,雙向關聯(lián)關系用帶雙箭頭的實線或者無箭頭的實線雙線表示。單向關聯(lián)用一個帶箭頭的實線表示拢肆,箭頭指向被關聯(lián)的對象减响,如圖9所示。這就是導航性(Navigatity)郭怪。
一個對象可以持有其它對象的數(shù)組或者集合支示。在UML中,通過放置多重性(multipicity)表達式在關聯(lián)線的末端來表示鄙才。多重性表達式可以是一個數(shù)字颂鸿、一段范圍或者是它們的組合。多重性允許的表達式示例如下:
- 數(shù)字:精確的數(shù)量
-
*
或者0..*
:表示0到多個 -
0..1
:表示0或者1個攒庵,在Java中經(jīng)常用一個空引用來實現(xiàn) -
1..*
:表示1到多個
關聯(lián)關系又分為依賴關聯(lián)嘴纺、聚合關聯(lián)和組合關聯(lián)三種類型。
4)依賴關系
依賴(Dependency)關系是一種弱關聯(lián)關系浓冒。如果對象A用到對象B栽渴,但是和B的關系不是太明顯的時候,就可以把這種關系看作是依賴關系裆蒸。如果對象A依賴于對象B熔萧,則 A “use a” B。比如駕駛員和汽車的關系僚祷,駕駛員使用汽車佛致,二者之間就是依賴關系。
在UML類圖中辙谜,依賴關系用一個帶虛線的箭頭表示俺榆,由使用方指向被使用方,表示使用方對象持有被使用方對象的引用装哆,如圖10所示罐脊。
依賴關系在Java中的具體代碼表現(xiàn)形式為B為A的構(gòu)造器或方法中的局部變量、方法或構(gòu)造器的參數(shù)蜕琴、方法的返回值萍桌,或者A調(diào)用B的靜態(tài)方法。
下面我們用代碼清單1和代碼清單2所示的Java代碼來演示對象和對象之間的依賴關系凌简。
代碼清單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)聚合關系與組合關系
聚合(Aggregation)是關聯(lián)關系的一種特例凸郑,它體現(xiàn)的是整體與部分的擁有關系裳食,即 “has a” 的關系。此時整體與部分之間是可分離的芙沥,它們可以具有各自的生命周期诲祸,部分可以屬于多個整體對象,也可以為多個整體對象共享而昨,所以聚合關系也常稱為共享關系救氯。例如,公司部門與員工的關系配紫,一個員工可以屬于多個部門径密,一個部門撤消了,員工可以轉(zhuǎn)到其它部門躺孝。
在UML圖中享扔,聚合關系用空心菱形加實線箭頭表示,空心菱形在整體一方植袍,箭頭指向部分一方惧眠,如圖11所示。
組合(Composition)也是關聯(lián)關系的一種特例于个,它同樣體現(xiàn)整體與部分間的包含關系氛魁,即 “contains a” 的關系。但此時整體與部分是不可分的,部分也不能給其它整體共享秀存,作為整體的對象負責部分的對象的生命周期捶码。這種關系比聚合更強,也稱為強聚合或链。如果A
組合B
惫恼,則A
需要知道B
的生存周期,即可能A
負責生成或者釋放B
澳盐,或者A
通過某種途徑知道B
的生成和釋放祈纯。
例如,人包含頭叼耙、軀干腕窥、四肢,它們的生命周期一致筛婉。當人出生時簇爆,頭、軀干倾贰、四肢同時誕生冕碟。當人死亡時,作為人體組成部分的頭匆浙、軀干安寺、四肢同時死亡。
在UML圖中首尼,組合關系用實心菱形加實線箭頭表示挑庶,實心菱形在整體一方,箭頭指向部分一方软能,如圖12所示迎捺。
在Java代碼形式上,聚合和組合關系中的部分對象是整體對象的一個成員變量查排。但是凳枝,在實際應用開發(fā)時,兩個對象之間的關系到底是聚合還是組合跋核,有時候很難區(qū)別岖瑰。在Java中,僅從類代碼本身是區(qū)分不了聚合和組合的砂代。如果一定要區(qū)分蹋订,那么如果在刪除整體對象的時候,必須刪掉部分對象刻伊,那么就是組合關系露戒,否則可能就是聚合關系椒功。從業(yè)務角度上來看,如果作為整體的對象必須要部分對象的參與智什,才能完成自己的職責动漾,那么二者之間就是組合關系,否則就是聚合關系撩鹿。
例如谦炬,汽車與輪胎悦屏,汽車作為整體节沦,輪胎作為部分。如果用在二手車銷售業(yè)務環(huán)境下础爬,二者之間就是聚合關系甫贯。因為輪胎作為汽車的一個組成部分,它和汽車可以分別生產(chǎn)以后裝配起來使用看蚜,但汽車可以換新輪胎叫搁,輪胎也可以卸下來給其它汽車使用。如果用在駕駛系統(tǒng)業(yè)務環(huán)境上供炎,汽車如果沒有輪胎渴逻,就無法完成行駛?cè)蝿眨咧g就是一個組合關系音诫。再比如網(wǎng)上書店業(yè)務中的訂單和訂單項之間的關系惨奕,如果訂單沒有訂單項,也就無法完成訂單的業(yè)務竭钝,所以二者之間是組合關系梨撞。而購物車和商品之間的關系,因為商品的生命周期并不被購物車控制香罐,商品可以被多個購物車共享卧波,因此,二者之間是聚合關系庇茫。