UML詳解之二——類圖
你也可以檢視我的其他同類文章,也會讓你有一定的收貨!
類(Class)
類圖(ClassDiagrams)是根據系統中的類以及各類之間的關係描述系統的靜態檢視。類圖不僅顯示系統內資訊的結構,還描述系統內這些資訊的行為。類圖的一個重要目的是為其他圖(如順序圖、互動圖)定義一個基礎。類圖由多個類以及這些類之間的關係組成。
在系統設計階段,類圖直接引導面向物件的程式語言實現類。類圖是生成程式碼的核心要圖。如果類圖設計得好,整個系統的程式碼框架可以有類圖自動生成,大大簡化了系統編碼所耗費的時間。因此,我們進一步:利用類圖,使得程式碼的編寫程式設計一種自動化工作,而整個資訊系統的建設中心都可以集中到分析設計上來。
.
類是物件的藍圖,其中包含3個組成部分。
- Java中定義的類名。
- 屬性(attributes)。
- 加號(+)表示具有公共可見性。
- 減號(-)表示私有可見性。
- #號表示受保護的可見性。
- 省略這些修飾符表示具有package(包)級別的可見性。
- 該類提供的方法。
- 在操作中,可同時列出它接受的引數,以及返回型別,
如果屬性或操作具有下劃線,表明它是靜態的。
如圖A的“Java”區域所示。
第一行 : 類名,如果是抽象類,則用斜體顯示.
第二行 : 欄位或屬性.
- +:表示public;
- -:表示:private;
- #:表示protected;
包(Package)
包是一種常規用途的組合機制。UML中的一個包直接對應於Java中的一個包。
在Java中,一個包可能含有其他包、類或者同時含有這兩者。
進行建模時:
- 通常擁有邏輯性的包,它主要用於對你的模型進行組織。
- 還會擁有物理性的包,它直接轉換成系統中的Java包。
- 每個包的名稱對這個包進行了惟一性的標識。
介面(Interface)
介面是一系列操作的集合,它指定了一個類所提供的服務。它直接對應於Java中的一個介面型別。
介面既可用圖C的那個圖示來表示,也可由附加了<< interface>>的一個標準類來表示。
通常,根據介面在類圖上的樣子,就能知道與其他類的關係。
它表示一個介面圖,與類圖的區別主要是頂端有<< interface>>顯示。第一行是介面名稱,第二行是介面方法。
介面還有另一種表示方法,俗稱棒棒糖表示法,就是唐老鴨類實現了‘講人話’的介面。”
類圖關係
1、依賴(Dependency)
定義:
對於兩個相對獨立的類,當一個類負責構造另一個類的例項,或者依賴另一個類時,這兩個類之間主要體現為依賴關係
屬性:
實體之間“使用”關係表示一個實體的規範發生變化後,可能影響依賴於它的其他例項(圖D)。
引用不在例項作用域內的一個類或物件的任何型別。
- 依賴的物件可以是被依賴方法中的一個引數或區域性變數(如下例所示)
- 對依賴類的靜態方法的引用(不存在那個類的一個例項)。
也可利用“依賴”來表示包和包之間的關係。由於包中含有類,所以你可根據那些包中的各個類之間的關係,表示出包和包的關係。
Java與UML對應圖:
舉例:
Bicycle類和Pump類之間是依賴關係,在Bicycle類中無需定義Pump型別的變數。Pump類物件是Bicycle類物件方法中的一個引數
Bicycle類的定義如下:
public class Bicycle{
/** 給輪胎充氣 */
public void expand(Pump pump){
pump.blow();
}
}
在現時生活中,通常不會為某一輛自行車配備專門的打氣筒,而是在需要充氣的時候,從附近某個修車棚裡借個打氣筒打氣。
在程式程式碼中,表現為Bicycle類的expand()方法有個Pump型別的引數。
以下程式程式碼表示某輛自行車先後到兩個修車棚裡充氣:
myBicycle.expand(pumpFromRepairShed1); //到第一個修車棚裡充氣
myBicycle.expand(pumpFromRepairShed2); //若干天后,到第二個修車棚裡充氣
2、關聯(Association)
定義:
對於兩個相對獨立的類,當一個類的例項與另一個類的例項存在固定的對應關係時,這兩個類之間為關聯關係。
屬性:
實體之間的一個結構化關係表明物件是相互連線的。
UML關係圖符號中關聯關係的箭頭是可選的,它用於指定導航能力。如果沒有箭頭,暗示是一種雙向的導航能力。
Java中的表現:
在Java中,關聯關係是使用例項變數實現的。
Java與UML對應圖:
就像圖E的“Java”區域所展示的程式碼那樣。可為一個關聯附加其他修飾符。多重性(Multiplicity)修飾符暗示著例項之間的關係。
在示範中,Employee可以有0個或更多的TimeCard物件。但是,每個TimeCard只從屬於單獨一個Employee。
舉例:
- 客戶和訂單,每個訂單對應特定的客戶,每個客戶對應一些特定的訂單;
- 公司和員工,每個公司對應一些特定的員工,每個員工對應一特定的公司;
- 而充電電池和充電器之間就不存在固定的對應關係,同樣自行車和打氣筒之間也不存在固定的對應關係。
Person類與Bicycle類之間存在關聯關係,這意味著在Person類中需要定義一個Bicycle型別的成員變數。以下是Person類的定義:
public class Person{
private Bicycle bicycle; //主人的自行車
public Bicycle getBicycle(){
return bicycle;
}
public void setBicycle(Bicycle bicycle){
this.bicycle=bicycle;
}
/** 騎自行車去上班 */
public void goToWork(){
bicycle.run();
}
}
在現時生活中,當你騎自行車去上班時,只要從家裡推出自己的自行車就能上路了,不像給自行車打氣那樣,在需要打氣時,還要四處去找修車棚。因此,在Person類的goToWork()方法中,呼叫自身的bicycle物件的run()方法。
假如goToWork()方法採用以下的定義方式:
/** 騎自行車去上班 */
public void goToWork(Bicycle bicycle){
bicycle.run();
}
那就好比去上班前,還要先四處去借一輛自行車,然後才能去上班。
3、聚合(Aggregation)
定義:
當系統A被加入到系統B中,成為系統B的組成部分時,系統B和系統A之間為聚集關係。
聚合(Aggregation)關係是關聯關係的一種,是強的關聯關係。
屬性:
聚合是整體和個體之間的關係。例如,汽車類與引擎類、輪胎類,以及其它的零件類之間的關係便整體和個體的關係。
- 關聯關係所涉及的兩個類是處在同一層次上的,
- 聚合關係中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分。
Java中的表現:
聚合關係也是通過例項變數實現的。
Java與UML對應圖:
UML關係圖符號中聚合是關聯的一種形式,代表兩個類之間的整體/區域性關係。
關聯和聚合的區別純粹是概念上的,而且嚴格反映在語義上。聚合關係的例項圖中不存在迴路。換言之,只能是一種單向關係。
舉例:
例如自行車和它的響鈴、龍頭、輪胎、鋼圈以及剎車裝置就是聚集關係,因為響鈴是自行車的組成部分。
聚合關係的類裡含有另一個類作為引數 。
雁群類(GooseGroup)的建構函式中要用到大雁(Goose)作為引數把值傳進來 大雁類(Goose)可以脫離雁群類而獨立存在
聚合關係圖:
public class GooseGroup
{
public Goose goose;
public GooseGroup(Goose goose)
{
this.goose = goose;
}
}
4、組合(合成)(Composition)
定義:
組合(圖G)是聚合的一種特殊形式,暗示“區域性”在“整體”內部的生存期職責。
屬性:
組合也是非共享的。所以,雖然區域性不一定要隨整體的銷燬而被銷燬,但整體要麼負責保持區域性的存活狀態,要麼負責將其銷燬。區域性不可與其他整體共享。比如你和你的大腦
但是,整體可將所有權轉交給另一個物件,後者隨即將承擔生存期職責。
Java中的表現:
組合關係也是通過例項變數實現的。
Java與UML對應圖:
Employee和TimeCard的關係或許更適合表示成“合成”,而不是表示成“關聯”。
舉例:
組合關係的類裡含有另一個類的例項化 。
大雁類(Goose)在例項化之前 一定要先例項化翅膀類(Wings) 兩個類緊密耦合在一起 它們有相同的生命週期 翅膀類(Wings)不可以脫離大雁類(Goose)而獨立存在
組合關係圖:
public class Goose
{
public Wings wings;
public Goose()
{
wings=new Wings();
}
}
5、泛化(Generalization)
定義:
表示類與類之間的繼承關係,介面與介面之間的繼承關係,或類對介面的實現關係;箭頭是從子類指向父類的,與繼承或實現的方法相反。
泛化表示一個更泛化的元素和一個更具體的元素之間的關係。UML關係圖符號中泛化是用於對繼承進行建模的UML元素。
Java中的表現:
在Java中,用extends關鍵字來直接表示這種關係。
Java與UML對應圖:
6、實現(Realization)
定義:
例項(圖I)關係指實現介面,箭頭指向介面
Java中的表現:
對Java應用程式進行建模時,實現關係可直接用implements關鍵字來表示。
Java與UML對應圖:
各個關係的區別
1、聚合和組合
在聚合關係中,客戶端可以同時瞭解雁群類和大雁類,因為他們都是獨立的
而在組合關係中,客戶端只認識大雁類,根本就不知道翅膀類的存在,因為翅膀類被嚴密的封裝在大雁類中。
(1)聚合與組合都是一種結合關係,只是額外具有整體-部分的意涵。
(2)部件的生命週期不同
- 聚合關係中,整件不會擁有部件的生命週期,所以整件刪除時,部件不會被刪除。再者,多個整件可以共享同一個部件。
- 組合關係中,整件擁有部件的生命週期,所以整件刪除時,部件一定會跟著刪除。而且,多個整件不可以同時間共享同一個部件。
(3)聚合關係是“has-a”關係,組合關係是“contains-a”關係。
2.關聯和聚合
(1)表現在程式碼層面,和關聯關係是一致的,只能從語義級別來區分。
(2)關聯和聚合的區別主要在語義上,關聯的兩個物件之間一般是平等的,例如你是我的朋友,聚合則一般不是平等的。
(3)關聯是一種結構化的關係,指一種物件和另一種物件有聯絡。
(4)關聯和聚合是視問題域而定的
例如在關心汽車的領域裡,輪胎是一定要組合在汽車類中的,因為它離開了汽車就沒有意義了。但是在賣輪胎的店鋪業務裡,就算輪胎離開了汽車,它也是有意義的,這就可以用聚合了。
3.關聯和依賴
(1)關聯關係中,體現的是兩個類、或者類與介面之間語義級別的一種強依賴關係,比如我和我的朋友;這種關係比依賴更強、不存在依賴關係的偶然性、關係也不是臨時性的,一般是長期性的,而且雙方的關係一般是平等的。
(2)依賴關係中,可以簡單的理解,就是一個類A使用到了另一個類B,而這種使用關係是具有偶然性的、臨時性的、非常弱的,但是B類的變化會影響到A。
4.綜合比較
這幾種關係都是語義級別的,所以從程式碼層面並不能完全區分各種關係;但總的來說,後幾種關係所表現的強弱程度依次為:
組合>聚合>關聯>依賴;