1. 程式人生 > >UML詳解之二——類圖

UML詳解之二——類圖

你也可以檢視我的其他同類文章,也會讓你有一定的收貨!

類(Class)

類圖(ClassDiagrams)是根據系統中的類以及各類之間的關係描述系統的靜態檢視。類圖不僅顯示系統內資訊的結構,還描述系統內這些資訊的行為。類圖的一個重要目的是為其他圖(如順序圖、互動圖)定義一個基礎。類圖由多個類以及這些類之間的關係組成。

在系統設計階段,類圖直接引導面向物件的程式語言實現類。類圖是生成程式碼的核心要圖。如果類圖設計得好,整個系統的程式碼框架可以有類圖自動生成,大大簡化了系統編碼所耗費的時間。因此,我們進一步:利用類圖,使得程式碼的編寫程式設計一種自動化工作,而整個資訊系統的建設中心都可以集中到分析設計上來。

這裡寫圖片描述.

是物件的藍圖,其中包含3個組成部分

  1. Java中定義的類名。
  2. 屬性(attributes)。
    • 加號(+)表示具有公共可見性。
    • 減號(-)表示私有可見性。
    • #號表示受保護的可見性。
    • 省略這些修飾符表示具有package(包)級別的可見性。
  3. 該類提供的方法。
    • 在操作中,可同時列出它接受的引數,以及返回型別,

如果屬性或操作具有下劃線,表明它是靜態的。

如圖A的“Java”區域所示。

圖A

  • 第一行 : 類名,如果是抽象類,則用斜體顯示.

  • 第二行 : 欄位或屬性.

    • +:表示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.綜合比較

這幾種關係都是語義級別的,所以從程式碼層面並不能完全區分各種關係;但總的來說,後幾種關係所表現的強弱程度依次為:

組合>聚合>關聯>依賴;