1. 程式人生 > >UML之類圖

UML之類圖

不一定 外部 中一 記錄 () for button mage 構造

一.類:通常可以分為三種,分別是實體類(Entity Class)、控制類(Control Class)和邊界類(Boundary Class),下面對這三種類加以簡要說明:

(1) 實體類:實體類對應系統需求中的每個實體,它們通常需要保存在永久存儲體中,一般使用數據庫表或文件來記錄,實體類既包括存儲和傳遞數據的類,還包括操作數據的類。實體類來源於需求說明中的名詞,如學生、商品等。

(2) 控制類:控制類用於體現應用程序的執行邏輯,提供相應的業務操作,將控制類抽象出來可以降低界面和數據庫之間的耦合度。控制類一般是由動賓結構的短語(動詞+名詞)轉化來的名詞,如增加商品對應有一個商品增加類,註冊對應有一個用戶註冊類等

(3) 邊界類:邊界類用於對外部用戶與系統之間的交互對象進行抽象,主要包括界面類,如對話框、窗口、菜單等。

在面向對象分析和設計的初級階段,通常首先識別出實體類,繪制初始類圖,此時的類圖也可稱為領域模型,包括實體類及其它們之間的相互關系。

二.類圖的定義

類圖(Class Diagram): 類圖是面向對象系統建模中最常用和最重要的圖,是定義其它圖的基礎。類圖主要是用來顯示系統中的類、接口以及它們之間的靜態結構和關系的一種靜態模型。

類圖的表示:

技術分享

(1) 第一部分是類名:每個類都必須有一個名字,類名是一個字符串。

(2) 第二部分是類的屬性(Attributes):屬性是指類的性質,即類的成員變量。一個類可以有任意多個屬性,也可以沒有屬性

UML規定屬性的表示方式為:

可見性 名稱:類型 [ = 缺省值 ]

(3) 第三部分是類的操作(Operations):操作是類的任意一個實例對象都可以使用的行為,是類的成員方法。

UML規定操作的表示方式為:

可見性 名稱(參數列表) [ : 返回類型]

三.建立類圖

在軟件開發不同階段使用的類圖具有不同的抽象層次,即概念層、說明層、和實現層。使用UML進行應用建模也應該是一個叠代的過程,所以我們應該建立一個類圖的層次的概念。

概念層類圖描述應用領域中的概念,這些概念與實現它們的類有聯系。通常沒有直接的映射關系。畫概念層類圖時很少考慮或不考慮實現問題,因此概念層類圖應獨立於具體的編程語言。下面是一個概念層類的表示。

技術分享

說明層類圖。此時我們考察的是類的接口部分,而不是實現部分。這個接口可能因為實現環境、運行特性等有多種不同的實現。下面是一個說明層類的表示。

技術分享

實現層類圖才真正考慮類的實現問題,提供實現的細節。此時的類的概念才應該是真正的嚴格意義上的類。它揭示了軟件實體的構成情況。實現層的類是最常用的,在很多的時候說明層的類更有助於人們對軟件的理解。

技術分享

UML的最終目標是識別出所有必須的類,並分析這些類之間的關系,類的識別貫穿於整個建模過程,分析階段主要識別問題域相關的類,在設計階段需要加入一些反映設計思想、方法的類以及實現問題域所需要的類,在編碼實現階段,因為語言的特點,可能需要加入一些其他的類。

建立類圖的步驟:

(1)研究分析問題領域確定系統需求。

(2)確定類,明確類的含義和職責、確定屬性和操作。

(3)確定類之間的關系。

4類之間的關系與JAVA實現: 關聯關系、依賴關系、泛化關系

1.關聯關系

在UML中,關聯關系通常又包含如下幾種形式:

(1) 雙向關聯

默認情況下,關聯是雙向的。例如:顧客(Customer)購買商品(Product)並擁有商品,反之,賣出的商品總有某個顧客與之相關聯。因此,Customer類和Product類之間具有雙向關聯關系,如圖2所示:

技術分享

圖2 雙向關聯實例

圖2對應的Java代碼片段如下:

public class Customer {
private Product[] products;
……
}

public class Product {
private Customer customer;
……
}

(2) 單向關聯

1、單向關聯

A1->A2: 表示A1認識A2,A1知道A2的存在,A1可以調用A2中的方法和屬性

技術分享

圖3 單向關聯實例

圖3對應的Java代碼片段如下:

public class Customer {
private Address address;
……
}

public class Address {
……
}

(3) 自關聯

在系統中可能會存在一些類的屬性對象類型為該類本身,這種特殊的關聯關系稱為自關聯。例如:一個節點類(Node)的成員又是節點Node類型的對象,如圖4所示:

技術分享

圖4 自關聯實例

圖4對應的Java代碼片段如下:

public class Node {
private Node subNode;
……
}

(4) 多重性關聯

多重性關聯關系又稱為重數性(Multiplicity)關聯關系,表示兩個關聯對象在數量上的對應關系。在UML中,對象之間的多重性可以直接在關聯直線上用一個數字或一個數字範圍表示。

對象之間可以存在多種多重性關聯關系,常見的多重性表示方式如表1所示:

表1 多重性表示方式列表

表示方式 多重性說明
1..1 表示另一個類的一個對象只與該類的一個對象有關系
0..* 表示另一個類的一個對象與該類的零個或多個對象有關系
1..* 表示另一個類的一個對象與該類的一個或多個對象有關系
0..1 表示另一個類的一個對象沒有或只與該類的一個對象有關系
m..n 表示另一個類的一個對象與該類最少m,最多n個對象有關系 (m≤n)

例如:一個界面(Form)可以擁有零個或多個按鈕(Button),但是一個按鈕只能屬於一個界面,因此,一個Form類的對象可以與零個或多個Button類的對象相關聯,但一個Button類的對象只能與一個Form類的對象關聯,如圖5所示:

技術分享

圖5 多重性關聯實例

圖5對應的Java代碼片段如下:

public class Form {
private Button[] buttons; //定義一個集合對象
……
}

public class Button {
……
}

(5) 聚合關系

聚合(Aggregation)關系表示整體與部分的關系。在聚合關系中,成員對象是整體對象的一部分,但是成員對象可以脫離整體對象獨立存在。在UML中,聚合關系用帶空心菱形的直線表示。例如:汽車發動機(Engine)是汽車(Car)的組成部分,但是汽車發動機可以獨立存在,因此,汽車和發動機是聚合關系,如圖6所示:

技術分享

圖6 聚合關系實例

在代碼實現聚合關系時,成員對象通常作為構造方法、Setter方法或業務方法的參數註入到整體對象中,圖6對應的Java代碼片段如下:

public class Car {
	private Engine engine;

    //構造註入
	public Car(Engine engine) {
		this.engine = engine;
	}
    
    //設值註入
public void setEngine(Engine engine) {
    this.engine = engine;
}
……
}

public class Engine {
	……
} 

(6) 組合關系

組合(Composition)關系也表示類之間整體和部分的關系,但是在組合關系中整體對象可以控制成員對象的生命周期,一旦整體對象不存在,成員對象也將不存在,成員對象與整體對象之間具有同生共死的關系。在UML中,組合關系用帶實心菱形的直線表示。例如:人的頭(Head)與嘴巴(Mouth),嘴巴是頭的組成部分之一,而且如果頭沒了,嘴巴也就沒了,因此頭和嘴巴是組合關系,如圖7所示:

技術分享

圖7 組合關系實例

在代碼實現組合關系時,通常在整體類的構造方法中直接實例化成員類,圖7對應的Java代碼片段如下:

public class Head {
	private Mouth mouth;

	public Head() {
		mouth = new Mouth(); //實例化成員類
	}
……
}

public class Mouth {
	……
} 

組合與聚合的區別:

聚合和組合的區別在於:聚合關系是“has-a”關系,組合關系是“contains-a”關系;聚合關系表示整體與部分的關系比較弱,而組合比較強;聚合關系中代表部分事物的對象與代表聚合事物的對象的生存期無關,一旦刪除了聚合對象不一定就刪除了代表部分事物的對象。組合中一旦刪除了組合對象,同時也就刪除了代表部分事物的對象。

2. 依賴關系

依賴(Dependency)關系是一種使用關系,特定事物的改變有可能會影響到使用該事物的其他事物,在需要表示一個事物使用另一個事物時使用依賴關系。大多數情況下,依賴關系體現在某個類的方法使用另一個類的對象作為參數。在UML中,依賴關系用帶箭頭的虛線表示,由依賴的一方指向被依賴的一方。例如:駕駛員開車,在Driver類的drive()方法中將Car類型的對象car作為一個參數傳遞,以便在drive()方法中能夠調用car的move()方法,且駕駛員的drive()方法依賴車的move()方法,因此類Driver依賴類Car,如圖1所示:

技術分享

圖1 依賴關系實例

在系統實施階段,依賴關系通常通過三種方式來實現,第一種也是最常用的一種方式是如圖1所示的將一個類的對象作為另一個類中方法的參數,第二種方式是在一個類的方法中將另一個類的對象作為其局部變量,第三種方式是在一個類的方法中調用另一個類的靜態方法。圖1對應的Java代碼片段如下:

public class Driver {
	public void drive(Car car) {
		car.move();
	}
    ……
}

public class Car {
	public void move() {
		......
	}
    ……
}  

3. 泛化(Generalization)

泛化表示一個更泛化的元素和一個更具體的元素之間的關系。泛化是用於對繼承進行建模的UML元素。在Java中,用extends關鍵字來直接表示這種關系。

技術分享

4. 實現(Realization)

實例關系指定兩個實體之間的一個合同。換言之,一個實體定義一個合同,而另一個實體保證履行該合同。對Java應用程序進行建模時,實現關系可直接用implements關鍵字來表示。

技術分享

接口之間也可以有與類之間關系類似的繼承關系和依賴關系,但是接口和類之間還存在一種實現(Realization)關系,在這種關系中,類實現了接口,類中的操作實現了接口中所聲明的操作。在UML中,類與接口之間的實現關系用帶空心三角形的虛線來表示。例如:定義了一個交通工具接口Vehicle,包含一個抽象操作move(),在類Ship和類Car中都實現了該move()操作,不過具體的實現細節將會不一樣,如圖4所示:

技術分享

圖4 實現關系實例

實現關系在編程實現時,不同的面向對象語言也提供了不同的語法,如在Java語言中使用implements關鍵字,而在C++/C#中使用冒號“:”來實現。圖4對應的Java代碼片段如下:

public interface Vehicle {
public void move();
}

public class Ship implements Vehicle {
public void move() {
    ……
    }
}

public class Car implements Vehicle {
public void move() {
    ……
    }
}

參考:http://www.uml.org.cn/oobject/201211231.asp?artid=3992,http://www.uml.org.cn/oobject/201008311.asp?artid=3996,http://www.uml.org.cn/oobject/201104212.asp?artid=3995,http://www.uml.org.cn/oobject/201210081.asp?artid=3966,http://www.uml.org.cn/oobject/201610282.asp?artid=18576,http://www.uml.org.cn/oobject/201007275.asp?artid=3968

UML之類圖