類圖是UML模型中靜態視圖。它用來描述系統中的有意義的概念,包括具體的概念、抽象的概念、實現方面的概念等。如在圖書館借閱系統中,圖書、借書、還書、讀者、超期罰款等,這些都是這個系統中的一些有意義的概念。
在前面的文章中曾經說過,靜態視圖包括類圖和對象圖。
這篇文章重點介紹類圖。
類圖(Class Diagram)是描述類、接口、協同以及他們之間關系的圖,用來顯示系統中這些概念的靜態結構。
類圖是其它圖的基礎。我們可以在類圖的基礎上,使用狀態圖、協作圖、組件圖和配置圖等。
類圖的主要作用有:
(1)對系統的詞匯進行建模
(2)對簡單的協作進行建模
(3)對邏輯數據庫模式進行建模
類圖主要由類、接口和各種關系組成。
關系主要包括泛化關系、依賴關系、關聯關系和實現關系。
下面將對這些內容進行詳細的講解。
在UML中,一個類通常由名稱(Name)、屬性(Attribute)和操作(Operation)構成。除此之外,類的構成還包含類的職責(Responsibility)、約束(Constraint)和注釋(Note)等信息。
在UML中,類使用下面的圖形來表示。
類的圖形符號從上到下分為三部分:類的名稱、類的屬性和類的操作。
在實際中可能還有如下三種形式:
類的名稱應該是一個名詞,類名應該準確清晰的反映出問題域中的概念。按照UML的約定,類的名稱中的每個詞的首字母應大寫,且使用正體名稱來表示可實例化的類,使用斜體名稱表示抽象的類。
上面圖的Book類就是一個可實例化的類,而下面的這個Shape類屬于抽象類。
抽象類的名稱使用斜體。
類的名稱可以加上路徑名稱。如下圖所示的例子:
上圖說明Order這個類來自Business包中。
也可以在命名時寫成如下的形式:
Business::Order
::左邊是包的名稱,右邊是類的名稱。
類的屬性(Attribute)用于描述類的一個特征,這個特征是類的每個實例所共有的。一個類可以有零到多個屬性。
在UML中,類的屬性定義語法如下:
[可見性] 屬性名稱 [:數據類型] [=初始值] [{屬性字符串}]
上面的語法中,[]中的內容表示是可選的。
(1)可見性
可見性用于控制該屬性被類的外部成員的可訪問性。主要有以下四種情況:
+:公有屬性,其它類可以訪問該屬性
-:私有屬性,不能被其它類訪問(默認為私有)
#:保護屬性,只能被本類及其派生類訪問
~:包內可見,可以被本包中的其它類訪問
(2)屬性名稱
能夠準確描述類特征的一個標識符,屬性名通常是一個名詞或名詞短語。一般單字屬性使用小寫字母,多字屬性從第2個單詞開始,每個單詞的第一個字符要大寫。
(3)數據類型
屬性所屬的數據類型,如布爾類型、整型、浮點型,也可以是用戶自定義的類型。
(4)初始值
屬性的默認值,在類的實例沒有賦其它值時,將采用該值作為該屬性的值。
(5)屬性字符串
用來指定該屬性的其它信息。任何希望進一步描述該屬性又沒有合適的地方時都可以放在此處。
以上關于屬性的描述內容雖然很多,但一般屬性的可見性和屬性名稱是必需的部分。
類的操作是類的行為特征或動態特征。類的操作相當于該類提供的一項服務,該服務可以由類的任何對象請求以影響其行為。操作在面向對象編程中通常被稱為函數或方法。
一個類可以擁有多個操作,也可以沒有操作。
在UML中,類的操作描述語法如下:
[可見性] 操作名稱 [(參數表)][:返回類型][{屬性字符串}]
(1)可見性
與屬性相同,規定該操作的可訪問范圍。
操作的可見性也是有+(公有)、-(私有),#(保護)和~(包內可見)四種。
從上到下分別為公有,保護和私有操作
(2)操作名稱
在實際建模中,操作名是用來描述所屬類的行為的動詞或動詞短語。在UML中,和屬性名的表示類似,單字的操作名小寫;多字的操作名,除第一個單詞外,其余單詞的開頭字母要大寫。
(3)參數表
是一些按順序排列的屬性定義了操作的輸入。
參數表是可選的。
參數的定義使用“名稱:類型”的定義方式。
如果存在多個參數,則將各個參數用逗號隔開。
參數可以具有默認值,適用調用時沒有提供參數值的情況。
如下面的time,其類型為Date,默認值為currentdate(即當前時間)
(4)返回類型
此項為可選項目,即操作不一定必須有返回類型。但在具體編程語言中使用void關鍵字來代表這種無返回值的情況。
(5)屬性字符串
任何在其它地方沒有描述清楚的內容都可以在這里進行描述。
在UML中,可以在操作部分的下面再添加一個區域,用來說明類的職責。即說明類或其它元素的契約或義務。
創建一個類時,同時聲明這個類的所有對象具有相同種類的狀態和相同種類的行為,在較高層次上,這些相應的屬性和操作正是要完成類的職責和特性。
職責可以使用一個短語、一個句子或一段短文的形式來描述。
在draw.io中,可以在“通用”組圖形中添加一個矩形,然后把矩形拖拽到類圖標上,當類周圍邊框變了顏色后,松開鼠標,就可以在類圖標的底部添加一個分隔的矩形,然后可以輸入類的職責相關描述。如下圖所示:
類的約束指定了該類所要滿足的一個或多個規則。
在UML中,約束使用一個大括號括起來的文本信息。
如上圖中類符號下面花括號中的內容,即是對該類的約束。
接口是在沒有給出對象的實現和狀態的情況下對對象行為的描述。
接口包含操作但不包含屬性,且它沒有對外界可見的關聯。
一個類可以實現一個或多個接口,從而支持接口所指定的操作。
接口可以使用下面兩種形式來表示:
使用<<interface>>構造型
使用一個圓圈
在類圖中的關系有四種:
依賴關系(dependency):表示類之間使用關系
泛化關系(generalization):表示一般和特殊關系
關聯關系(association):表示對象之間結構關系
實現關系(realization):表示規格說明和實現之間關系
它表示這樣一種情形,對于一個元素(提供者)的某些改變可能會影響或提供消息給其它元素(客戶),即客戶以某種形式依賴于其它類元。
主要的情形為:
客戶類的操作需要提供者類的參數;
客戶類的操作返回提供者類;
客戶類的操作在實現中使用提供類的對象。
下面舉個例子來說明這三種情形:
使用Java程序來表示上面這種情形:
上面這段代碼表示了常見類之間依賴關系的三種情形:提供者類作為參數、提供者類作為方法的返回類型、提供者類作為方法中的一個變量。
該關系是存在于一般元素和特殊元素之間的分類關系。其中,特殊元素與一般元素兼容,且還包含自己特有的信息。
泛化可以用于類、接口、用例、參與者、包、狀態機以及其它模型元素。
泛化關系描述的是“is a kind of”的關系。
泛化關系使用帶空心三角形的箭頭來表示,箭頭從子類指向父類。
下面是一個車輛Vehicle與Truck之間的泛化表示。
實現這種關系的Java代碼如下:
關聯關系是一種結構關系,指出了一個事物的對象與另一個事物的對象之間的語義上的連接。
關聯的任何一個連接點都叫做關聯端。關聯端可以有自己的角色、多重性、可見性等修飾。關聯也可以有自己的名稱。
在UML中,關聯關系用一條連接兩個類的實線表示。
上面的圖中,“擁有”為關聯的名稱,“客戶”為類Person的角色,“交通工具”為類car的角色。角色也可以有自己的可見性,“客戶”和“交通工具”前的“+”即代表其可見性為公有。
關聯端的“1”和“0..n”是描述的多重性,下面將會做進一步的介紹。
關聯的多重性(Multiplicity)是指有多少個對象可以參與該關聯。
其可用來表達一個取值范圍、特定值、無限定的范圍或一組離散值。
多重性是UML中使用最廣泛的約束。
主要有以下幾種形式:
形式 | 含義 | 形式 | 含義 |
0 | 恰為0 | 0..n | 0到多個 |
1 | 恰為1 | 1..n | 1到多個 |
0..1 | 0或1 | 3..n | 3到多個,至少3個 |
n | 0或多個 | 3,5,7 | 3個,或5個,或7個 |
關聯關系又可以分為單向關聯、雙向關聯、自關聯、聚合關聯和組合關聯四種情形。
(1)單向關聯
單向關聯用帶箭頭的實線表示。箭頭由源類指向目標類。
這種關聯實際上是帶導航的關聯。它指在源類中要使用目標類的對象作為成員。
上面類之間的關系可以使用下面的Java代碼來表示:
(2)雙向關聯
雙向關聯關系不再繪制箭頭,使用直線直接連接兩個類即可,如下面兩個類之間的關系即是雙向關聯關系:
實現這種關系的Java代碼可以如下表示:
帶有角色修飾的雙向關聯:
實現這種關聯關系的Java代碼可表示如下:
(3)自關聯
自關聯關系即一個類與自己進行關聯。
上面類關系的意思是employee類中有一個為employee類型的leader成員,表示員工的領導。
使用Java代碼可以表示如下形式:
public class employee{ private employee leader;}
(4)聚合關聯
它表示整體與部分關系的關聯。
關聯關系中一組元素組成了一個更大、更復雜的單元
聚合關系描述了“has a ”的關系。
在UML中聚合關系用帶空心菱形頭的實線來表示,頭部指向整體。
這種關系中的空心菱形并不是箭頭,它只表明哪端是整體。
聚合的雙向關聯的一個例子:
它表示College類是University類的一個聚合成分。
使用Java實現的代碼如下所示:
如果是單向的可以使用下面的方式來表示:
跟上面那個例子的區別是,這種聚合關聯只在University類中聲明College類的成員對象,不在College類中聲明University的成員對象。
使用Java代碼實現如下:
當然單向的聚合關系也可以表示下圖的形式:
使用Java代碼實現如下:
這樣的聚合表示沒太大意義。
(5)組合關聯
是聚合的一種特殊情況,是更強形式的聚合(即強聚合)。
成員的生命周期取決于聚合的生命周期。
聚合不僅控制著成員對象的行為,而且控制著成員對象的創建和解構。
在UML中,組合使用帶實心菱形頭的實線來表示,其菱形在整體這一端。
上面的Triangle類由多個Side類對象組合而成,當Triangle對象創建時,Side的對象被創建,Triangle對象被銷毀時,其Side對象也將被銷毀。
使用Java代碼實現如下:
是關于規格說明和其實現之間的關系,它將一種模型元素與另一種模型元素連接起來,比如類和接口。
實現關系將不同語義層上的元素連接起來。
實現關系不僅使用于接口和類之間,也可以是類的不同等級之間的聯系,如粗設計與細設計之間。
實現一般使用帶空心三角形的虛線箭頭表示,箭頭指向接口。
下面是關于接口和實現接口類之間的標識方法。
下面是一個具體的接口和實現之間的例子。
IUser是一個接口,VipUser是一個類,VipUser類要實現接口IUser。
其Java代碼可以表示成下面的形式:
建立類圖的過程就是對領域問題及其解決方案的一個分析和設計的過程。
關鍵是要準確地找出現實世界的對象類和類之間的聯系。
建立類圖的一般步驟:
研究分析問題領域,確定系統的需求。
發現對象與對象類,明確他們的含義和責任,確定屬性和操作。
發現類之間的靜態聯系;
設計類與聯系;
繪制類圖并編制相應的說明。
下面繼續以前面文章中(UML系列內容之五:一個用例圖案例)介紹的案例來設計其類圖。
案例中可以分析出以下幾個類:
經過認真分析類之間的關系,使用Rose工具繪制的類圖如下:
以上內容僅供參考,如有問題,請留言說明。
新聞熱點
疑難解答