在面向對象方法中,類圖是最重要的模型圖,它描述了系統中各個對象的類型和它們之間存在的各種關系。建立類圖是模組化中最基本的任務。
一張類圖應該注重表達系統靜态結構的一個方面,這意味,若是系統較為複雜,可能要繪制多張類圖。類圖是描述類、協作(類或對象間的協作)、接口及其關系的圖。
[提示]本講義由于圖檔多達30幾處,格式轉換會有問題,故沒有送出圖檔。請大家直接下載下傳PDF圖文閱讀,下載下傳位址:
http://download.csdn.net/detail/wojiushiwo987/9410741OOA模型
4.1 類圖的概念
類圖(Class diagram)是最常用的UML圖,顯示出類、接口以及它們之間的靜态結構和關系;我們常用類圖描述系統的結構。
4.1.1類圖
類圖是描述類、協作(類或對象間的協作)、接口及其關系的圖。與所有UML的其它圖一樣,類圖可以包括注釋、限制、包。圖4-1是一個典型的類圖。
類圖中的關系包括:、繼承關系(inheritance)/泛化關系(Generalization)、關聯關系(Association)、聚合關系(aggregation)、依賴關系(Dependency)。
圖4-1電子商務網站的對象模型
4.1.2類圖的作用
類圖常用來描述業務或軟體系統的組成、結構和關系。我們通常通過下面三種方式使用類圖:
(1)為系統詞彙模組化型
為系統的詞彙模組化實際上是從詞彙表中發現類,發現它的責任。
(2)模型化簡單的協作
協作是指一些類、接口和其他的元素一起工作,提供一些合作的行為,這些行為不是簡單地将元素加在一起就能實作的。例如:當我們為一個分布式的系統中的事務處理過程建立模型時,我們不可能隻通過一個類來表明事務是怎樣執行的,事實上這個過程的執行涉及到一系列的類的協同工作。使用類圖來可視化這些類和他們的關系。
(3)模型化一個邏輯資料庫模式
我們常用類圖設計資料庫的藍圖。在很多領域,我們想把持久性資料儲存到關系資料庫或面向對象的資料庫中。我們可以用類圖為這些資料庫模式建立模型。
4.1.3類圖的組成元素
類圖中的元素有類、接口、協作、關系、注釋、限制、包。關系把類、協作、接口連接配接在一起構成一個圖。注釋的作用是對某些類和接口進行注釋,限制的作用是對某些類和接口進行限制。
4.1.4對象與類的概念
(1)對象是具有明确語義邊界并封裝了狀态和行為的實體,即它是系統中用來描述客觀事物的一個實體,是構成系統的一個基本機關,由一組屬性和作用在這組屬性上的一組操作構成。
按照面向對象的封裝和資訊隐蔽原則,一個對象的屬性和操作時緊密結合的,對象的屬性應該隻由這個對象的操作存取。
(2)類是對具有相同屬性、操作、關系和語義的對象集合的描述, 也就是說它為屬于該類的全部對象提供了統一的抽象描述。對象是類的執行個體。
一個類的所有對象具有相同的屬性,是指所有對象的屬性的個數、名稱、資料類型都相同,但各個對象的屬性值可以互不相同,并且随着程式的執行而變化。操作對于一個類的所有對象都是一樣的,即所有的對象共同使用他們類的定義中給出的操作方法。
(3)類和對象的關系
①類是一組對象,這些對象具有共同的屬性和共同的行為
②類是建立對象的模闆
③類可捕獲對象的本質
④類是對象的抽象,而對象則是類的執行個體,或者說是類的具體表現形式
如同一個模具與用這個模具鑄造出來的鑄件之間關系。根據實際需要,通過對具有相同性質的事物的抽象,構造出模具,再用模具生産出具有這樣性質的鑄件。
圖4-2類和對象的關系
1
在面向對象方法中,通過對具有相同性質的對象的抽象,構造出類,進而使用類構造出系統模型;在系統運作時,又由類建立出對象。正是所建立的這些對象在計算機中的運作,完成了使用者所要求的功能。
4.1.5 類的種類
1.抽象類
在進行類設計時,如果一些具體類具有相同的方法或屬性,我們可以把這些相同的方法或屬性從這些具體類中抽取出來,把它們封裝到一個抽象類中,然後,通過擴充抽象類,重新定義這些具體類。
抽象類是一種不能直接執行個體化的類,也就是說不能用抽象類建立對象。
在UML中,抽象類和抽象方法的表示是将其名字用斜體表示。但是由于斜體字在草圖中不容易表現,是以推薦用《abstract》構造型來表示。圖4-7中列出這兩種不同的表示方法。
圖4-7 抽象類的2種表示方法
抽象類shape(圖形)中定義三個方法,drew()、getarea()是抽象方法,getboundingarea()是具體方法。在squre(正方形)和circle(圓形)兩個子類中,沒有定義getboundingarea(),确定義了drew()和getarea()方法。
抽象類shape定義的draw()和getarea()是抽象操作,在不同的子類中,其實作方法是不同的,即,在square和circle類中,對上面兩個抽象方法,有不同的實作。
2.主動類
從運作的角度來看,還有一種特殊的類-主動類,主動類的執行個體稱為主動對象,一個主動對象擁有一個控制線程并且能夠控制線程的活動,具有獨的控制權。
例如,指令處理程式就是一個主動類的例子,它從外面接受指令對象,然後在自身的控制線程内執行指令。在第二章中,曾經說明UML1.0中主動類的表示方法(普通類的基礎上加上粗邊界),但是在UML2.0中修改了主動類的表示法(在類的兩邊加上垂直線)。
3.模版類
在注入c++這樣語言中,提供了一種叫做參數化類(parameterized class)的機制,或叫做模版(template)。例如,我們需要一些能過處理整型、浮點型、字元串的數組,普通的做法是為它們各建立一個類,這三個類除了資料類型不同之外,其他的都是相同,但是仍然要定義三次。
模版就是用來解決這個問題,可以根據占位符或者參數來定義類,而不用說明屬性、方法傳回值和方法參數的實際類型。通過實際值代替占位符即可建立新類。這樣,就可以采用如圖4-8所示的設計方案。
圖4-8 模闆類
4.嵌套類
在諸如Java的語言中,允許你将一個類的定義放在另一個類定義的内部,這就是嵌套類,在Java中也稱為内層類。嵌套類是聲明在它的外層類中的,是以隻能夠通過外層類或外層類的對象對它進行通路 ,在UML中,可以采用一個描圖示來表示這種關系,如圖4-9所示。
圖4-9 嵌套類表示法
4.2屬性與操作
UML中,表示一個類,主要是辨別它的名稱、屬性和操作。如圖4-3所示,類由一個矩形表示,它包含3欄,在每欄中分别寫入類的名稱、類的屬性和類的操作。
圖4-3 Order類
用一個水準線劃分成三個分欄的實線矩形表示類。在最上面的那個分欄放類名,中的分欄放屬性清單,最下面的分欄放操作清單,每個屬性和操作都各占一行,下圖(a)給出的是表示一般類的符号。由于對象是類得執行個體,一個類的各個對象所擁有的操作都是相同的,是以對于對象隻需描述對象名和其屬性,下圖(b)給出的是表示對象的符号。
1.名稱
每個類都必須有一個有别于其他類的名稱, 類名部分是不能省略的,其他組成部分可以省略。名稱(Name)是一個文本串,表示方法有兩種:
(1)簡單名:如圖4-3中的Order(訂單),它就隻是一個單獨的名稱。
(2)全名:也稱為路徑名,就是在類名前面加上包的名稱,例如java::awt::Rectangel、businessRule::order等。
對于類的命名規範要求,由字元、數字、下劃線組成的惟一的字元串即可。但在實際應用中,有一個普遍采用的命名原則:采用CamelCase格式(大寫字母開頭、混合大小寫,每個單詞以大寫開始,避免使用特殊符号),盡可能避免使用縮寫。
2.屬性
屬性描述了類的靜态特征,在面向對象程式設計中,把屬性表示為成員變量。例如,在圖4-3所示的Order類中,列出了orderDate(下訂單時間)、destArea(送貨區域)、price(訂單總價格)、paymentType(支付類型)四個屬性,它們是用來描述每個具體的訂單對象的。
在屬性的前面有一個修飾,用來表示屬性的可見性,屬性的可見性一般都是private,這樣才符合面向對象的“封裝”思想。通常屬性名的第一個字母是小寫的。
3.操作
操作是類所提供的服務,是對象被要求執行的服務。通俗地說,操作就是定義了對象所能做的事情。在面向對象程式設計語言中,它通常表示為成員方法。對于操作的圖示,有以下幾點需要說明:
(1)操作名的命名規範也未硬性規定的,大家習慣采用和屬性名相同的命名規則。
對于操作,也經常會提供可見性修飾,隻是通常應該聲明為public,否則它難以向其他類提供服務。
(2)操作在表示時可以隻寫出操作名,也可以将操作擁有的參數也寫出來,即寫成員方法的完整簽名。
(3)屬性和操作名之前可附加的可見性修飾符:
加号(+)表示public(共有的);
減号(-)表示private(私有的);
‘#’号表示protected(受保護的);
~号表示包範圍的。
省略這些修飾符表示具有package(包)級别的可見性。 如果屬性或操作名具有下劃線,則說明它是靜态的。
4.職責
職責指類承擔的責任和義務。在矩形框中最後一欄中寫明類的職責。如圖4-4所示。
圖4-4 職責的表示
5.限制
限制指定了類所要滿足的一個或多個規則。 在UML中,限制是用花括号括起來的自由文本。如圖3-4所示。
圖4-5限制的表示
舉例如下:
其對應的類操作、執行個體操作的表示法為:
圖4-6類圖表示示例
4.3 類圖中的關系
類不是孤立存在的,是以,類與類之間建立了一種關系。按照關系的性質,把關系分為4種,它們是泛化關系、關聯關系、聚合關系、依賴關系。
圖4-10 類關系
下面分别說明其語義。
4.3.1泛化關系
定義:如果類A具有類B得全部屬性和全部操作,而且還具有自己特有的一些屬性或者操作,則A叫做B的特殊類,B叫做A的一般類,A與B之間的關系稱為繼承關系。
繼承關系又叫做一般—特殊關系,在UML中把繼承關系稱為泛化關系。
是從特殊元素到一般元素的分類關系稱為泛化關系。模型元素可以是類、用例以及其他。表示法:繼承可表示為從特殊類到一般類的一條實線,在一般類的那端有一個空心三角。如圖4-11所示:
圖4-11 泛化關系
繼承是一種使使用者得以在一個類的基礎上建立新的類的技術。新的類自動繼承舊類的屬性和行為特征,并可具備某些附加的特征或某些限制。新類稱作舊類的子類,舊類稱作新類的超類。
繼承的優點:能有效地支援軟體構件的重用,使得當需要在系統中增加新的特征時,所需新代碼最少。繼承機制的強有力之處還在于它允許程式設計人員可重用一個未必完全符合要求的類,允許對該類進行修改而不至于在該類的其它部分引起有害的副作用。繼承性是
面向對象程式設計語言不同于其它語言的最主要特點是其它語言所沒有的。
結構 說明 文法
泛化 它是較一般類和較具體類之間的分類關系
①泛化:辨別各個類之間的共同性。
②指明特化類(子類)的對象可取代泛化類(父類)的對象。
③是“is-a”關系。
詳解泛化關系如下圖所示:
圖4-12 泛化關系(列印機)
4.3.2關聯關系
1.基本概念
定義:如果一個類的對象與另一個類的對象之間有語義連接配接關系,那麼這兩個類之間的語義關系就是關聯。
表示法:把二進制關聯表示成連接配接兩個類符号的實線。在關聯的實線上,可以給出關聯的名稱,可以在關聯的端點上給出關聯的一些性質。關聯可以有方向,如果要限制關聯的通路方向,就要在關聯上加上一個表示方向的箭頭。
如圖所示:
關聯是類之間的一種關系,在類執行個體化後,這種關系将落實到每一組具有這種關系的對象之間。例如,類“教師”和類“學生“之間存在着關系“指導畢業論文”,這種關系所表達的資訊是:類“教師”和類“學生”之間存在着關系“指導畢業論文”,這種關系所表達的資訊是:類“教師”的對象和類“學生”的對象之間存在一種聯系,其語義是表明某個(些)教師為某個(些)學生指導畢業論文。至于誰給誰指導畢業論文,要到實作時才能确定,甚至要到系統傳遞使用後由使用者指定。把類之間的這種靜态關系稱為關聯。
把二進制關聯( binary association)表示成連接配接兩個符号的實線。為了避免與其他圖符号交叉,可以把實線劃成折線。表示關聯的實作的兩個端點可以連接配接到相同的類或不同的類,但是端點是不同的,是以要在各個端點的實線上可以給出關聯的名稱。
如果沒有對關聯指定方向,從關聯的任意一段都可以通路另一端,即通過關聯的通路是雙向的。如果要限制關聯上的通路方向,就要在關聯上加上一個表示方向的箭頭。如下圖所示:
單向關聯的表示法示例
如上圖所示,給定一個使用者就能找到他可能擁有的密碼,但反過來給定一個密碼就不需要去找響應的使用者。這種導向是單項性,就是通過“密碼”類的那一端在關聯線上加一個箭頭來說明的。
2.多重性
如下圖所示:
通常在關聯的兩端寫有表示數量限制的數字或符号,把他們稱為關聯的多重性(multiplicity)。關聯的另一端上的多重性是指,本段的一個對象所可能需要的另一端對象的個數。
上圖所示含義:一名學生擁有一份或多份成績單,一份成績單隻能被一名學生所擁有。
一個多重性描述的數量範圍可由一系列的正整數區間來指明,各區間由逗号分開。區間的格式為:
下限 .. 上限
其中的下限和上限均可為正整數值,下限也可為0,上限也可為。如果多重性由單個的“”構成,那麼它表明的範圍為任意的正整數範圍,它等價于0.. *。
示例:假設左類為A,給定A的一個對象a,右側關聯類為B
1 表示a 恰好與類B的一個對象關聯;
0..1 表示a 最多與類B的一個對象關聯;
1..* 表示a 與類B的一個或多個對象關聯;
0..* 表示a 與類B的零個或多個對象關聯。
如下圖:
說明:一名教師可以是一個系的系主任,也可以不是任何系的系主任;一個系隻有一名教師作為其系主任。
3.關聯角色
在關聯的每一個端點上可以有一個名字,用以表示與該關聯的端點相連接配接的類所扮演的角色,把這個名字稱為關聯角色名。
通常用名詞為關聯的角色命名。如上圖紅色标記的關聯角色為“任系主任”。使用關聯角色有助于了解關聯。
4.關聯類
在應用當中,我們發現兩個類之間具有多對多的關系,并且有些屬性不屬于關聯兩端任何一個類,例如,在某個應系統中有兩個類:person(人)和institute(協會),顯然person可以屬于多個institute,而每個institute肯定會吸納很多person。是以它們之間很顯然就是一個多對多的關系。
如果要記錄每個person在所屬的institute所擔任的職務,應該把這個職務屬性放在哪個類中呢?這個屬性既不屬于person,也不屬于institute。顯然,這個屬性應該放在關聯類中(Role),如圖4-12所示。
圖4-12關聯類Role
實際上關聯類既是關聯又是類,它不僅象關聯那樣連接配接兩個類,而且可以定義一組屬于關聯本身的特性。
注意:隻有關聯每一端的對象是1:1對應時,才能建立關聯類。
關聯 (association)是類之間的一種連接配接。是對象之間的長期關系。通常是雙向的。
①識别類之後,需要識别關聯
②如果類與類之間的聯系是單向的,則稱為單向關聯(導航關聯)
③多重性(multiplicity)定義有多少對象參與了某個關系
示例如下:
示例:“雇員為公司工作”
圖4-13單向關系
關聯關系是比較抽象的高層次關系,為了對關聯進一步具體化,我們需要了解關聯的屬性。關聯的屬性包括名稱,角色,多重性,限定,導航。
1)名稱
可以使用一個動詞或動詞短語給關聯取名,用來描述關聯的性質。在描述關聯時,關聯的名稱并不是必需的,在關聯名和角色中選一即可。可以在關聯上辨別閱讀方向的方向訓示符,以消除閱讀的歧義。
下面的例子表示,關聯名稱是”使用” ,即,使用者使用計算機。
圖4-14關聯名稱
2)角色
在關聯關系中,角色表明了關聯的每一端在關聯中承擔的職責,即,關聯發生時,關聯的每一端在關聯中扮演的角色。角色的名稱應該是名詞或名詞短語,以解釋對象是如何參與關聯的。如圖4-15關聯的角色。
圖4-15關聯的角色
學生在關聯中,扮演的是學習者的角色;學校扮演的是教學者的角色。
3)多重性
多重性就是某個類有多少個對象可以和另一個類的單個對象關聯。如圖4-16所示。
圖4-16關聯的多重性
上圖的多重性表示:一個學校可以有多個學生學習;一個學生可以到多個學校去學習,或不去任何學校學習。
4)導航性
導航性描述了源對象通過連結通路目标對象。箭頭表明了導航的方向性,即,隻有源對象才能通路目标對象,反之,目标對象不能通路源對象。如圖4-17所示。
圖4-17導航性
5)限定符
如果源對象到目标對象是1對多關聯,為了在多個目标對象的集合中查找到需要的目标對象,我們必須在目标對象集合中,選一個唯一辨別目标對象的查找鍵(限定符,從目标對象的屬性中選擇),它應該是目标對象中的某個屬性,當然,也可以是表達式。
圖4-18限定符
一個俱樂部(Club)可以有多個成員(Member),為了在成員集合(目标對象)上找到需要的對象,我們選擇memberId作為查找關鍵字,即,限定符。
4.3.3聚合關系
基本概念:
聚合(aggregation)是表示整體的類和表示部分的類之間的“整體—部分”關系。一個類的對象,以另一個類的對象作為其組成部分,這樣的對象之間具有“一部分”或“有一個”的語義。也可以了解為,一個類的定義應用了另一個類的定義。
組合(composition)是聚合的一種形式,一個部分類的對象在一個時刻至多屬于一個整體類的對象,且整體類的對象管理它的部分類的對象。
組合關系仍然是整體與部分之間的關系,隻是多了語義限制,故說它是聚合的一種形式。
在聚合關系中,把作為“整體”的類稱為聚集,作為“部分”的類稱為成分。
聚合 一種特殊形式的關聯,指定了聚合體(整體)和局部之間的關系
①共享聚合(空心菱形)意味着在組合端的多重性有多個。
②模拟“整體-局部”關系。
例如,大學由多個學院組成。
圖4-19 聚合關系
組合 一種特殊形式的關聯。是一種整體和部分所屬更強的聚集關系。每個部分隻能屬于一個整體。
①這是一種更強的聚合,表達了類與類之間更強的耦合
②組合的圖形為實心菱形。
③容器負責建立和删除各個部分。
例如,視窗中的菜單和按鈕不能離開視窗獨立存在,是以,是組合關系。
圖4-20組合關系
4.3.4依賴關系
定義:依賴是兩個模型元素之間的一種語義關系,它表明對目标元素的改變可能需要改變該關系中的源資料。
依賴可表示為兩個模組化元素之間的虛箭頭。在箭頭尾部的模型元素(源元素)依賴箭頭頭部的模型元素(目标元素)。可以用放在雙尖括号内的字元串辨別箭頭,如用況圖中的《include》和《extend》。
表示兩個或多個模型元素之間語義上的關系, 客戶元素以某種形式依賴于提供者元素。 實際上,關聯、實作和泛化都是依賴關系。 如圖4-21所示。
圖4-21 依賴關系
依賴 如果一個類依靠另一個類的服務來完成其角色,則它們之間的關系稱為依存關系
依賴關系指明兩個或多個類之間的語義關系,盡管兩個類之間沒有明确的關聯,一個類發生變化也會導緻另一個類發生變化。
依賴關系可以細分為4大類:使用依賴、抽象依賴、 授權依賴、 綁定依賴。
(1)使用依賴
表示客戶使用提供者提供的服務,以實作它的行為,下面都屬于使用依賴的具體形式:
使用(《use》)
調用(《call》)
參數(《parameter》)
發送(《send》)
執行個體化(《instantiate》)
(2)抽象依賴
表示客戶與提供者之間的關系,客戶與提供者屬于不同的抽象事物,具體依賴形式:
跟蹤(《trace》)
精化(《refine》)
派生(《derive》)
(3)授權依賴
表達一個事物通路另一個事物的能力,具體依賴形式:
通路(《access》)
導入(《import》)
友元(《friend》)
(4)綁定依賴
綁定依賴屬于較進階的依賴類型,用綁定模闆以建立新的模型元素,具體依賴形式:綁定(《bind》)
4.4接口
在接口定義為一個類的對外可見的一組操作的描述符,它定義了類對外提供的服務。
一個類可以實作一個或者多個接口,也稱類提供了一個或者多個接口。一個或多個類可使用一個或者多個接口,也稱類依賴一個或者多個接口。
接口是一種類似于抽象類的機制,接口中的方法都是抽象方法。在UML中,接口有如圖4-24所示的兩種表示方法。
圖4-24 接口的兩種表示法
圖示表示方法的優點是簡單,它隻适用于隻有單個操作的接口和草圖應用中。構造符号表示法是采用類(interface實際上是一種特殊的類)的方式表示,它的優點是可以添加多個抽象方法,具有更強的表示能力。
接口有兩種表示方法:
圖4-25用類表示的接口示例
上述的帶空心箭頭的虛線表示實作關系。上圖中類“傳感器”實作了“傳感器接口”,類“警報器”使用接口“傳感器接口”。
圖4-26簡化形式的接口示例
4.5如何建立對象模型
下面通過一個簡單的例子來說明建立對象模型的過程。
4.5.1 問題陳述
小劉是一個愛書之人,家裡各類書籍已過千冊,而平時又時常有朋友外借,是以需要一個個人圖書管理系統。該系統應該能夠将書籍的基本資訊按計算機類、非計算機類分别建檔,實作按書名、作者、類别、出版社等關鍵字的組合查詢功能。在使用該系統錄入新書籍時系統會自動按規則生成書号,可以修改資訊,但一經建立就不允許删除。該系統還應該能夠對書籍的外借情況進行記錄,可對外借情況清單列印。另外,還希望能夠對書籍的購買金額、冊數按特定時限、周期進行統計。
4.5.2 尋找分析類
我們以問題陳述為輸入資訊,采用“名詞動詞法”尋找分析類。名詞動詞法的主要規則是從名詞與名詞短語中提取對象與屬性;從動詞與動詞短語中提取操作和關聯。
1.找備選類
首先。可以逐字逐句地閱讀上面那段需求描述,并将其中的所有的名詞及名詞短語列出來,可以得到備選類清單。
2.從備選類中篩選出候選類
并不是所有的備選類都是适合候選類,有些名詞對于要開發的系統來說無關緊要。甚至不屬于系統;而有些名詞表述的概念則相對較小,适合某個候選類的屬性。是以,需要對備選類進行一番篩選,将這些不适合的排除掉。
(1)“小劉”、”人”、”家裡”很明顯是系統外的概念,無須對其模組化;
(2)而“個人圖書管理系統”、“系統”指的就是将要開發的系統,即系統本身,也無須對其進行模組化;
(3)很明顯“書籍”是一個很重要的類,而“書名”、“作者”、“類别”、“出版社”、“書号”則都是用來描述書籍的基本資訊的,是以應該作為“書籍”類的屬性處理,而“規則”是指書号的生成規則,而書号則是書籍的一個屬性,是以“規則”可以作為編寫“書籍”類構造函數的指南。
(4)“基本資訊”則是書名、作者、類别等描述書籍的基本資訊統稱,“關鍵字”則是代表其中之一,是以無需對其模組化;
(5)“功能”、“新書籍”、“資訊”、“記錄”都是在描述需求時使用到的一些相關詞語,并不是問題域的本質,是以先可以将其淘汰掉;
(6)“計算機類”、“非計算機類”是該系統中圖書的兩大分類,是以應該對其模組化,并改名為“計算機類書籍”和“非計算機類書籍”,以減少歧義;
(7)“外借情況”則是用來表示一次借閱行為,應該成為一個候選類,多個外借情況将組成“外借情況清單”,而外借情況中一個很重要的角色是“朋友”—借閱主體。雖然到本系統中并不需要建立“朋友”的資料庫,但考慮到可能會需要列出某個朋友的借閱情況,是以還是将其列為候選類。為了能夠更好地表述,将“外借情況”改名為“借閱記錄”,而将“外借情況清單”改名為“借閱記錄清單”;
(8)“購買金額”、“冊數”都是統計的結果,都是一個數字,是以不用将其模組化,而“特定時限”則是統計的範圍,也無需将其模組化;不過從這裡的分析中,我們可以發現,在該需求描述中隐藏着一個關鍵類—書籍清單,也就是執行統計的主體。
通過上面的分析,得到一個候選清單:
書籍 計算機類書籍 非計算機類書籍
借閱記錄 借閱記錄清單 書籍清單
4.5.3 确定類關系
通過上面的工作,從需求描述中找到了6個相關的類,接下來就是确定類之間的關系。
1.确定類關系
可以發現“計算機書籍(itbook)”、“非計算機書籍(otheritbook)”與“書籍(book)”之間是繼承關系;而“書籍清單(booklist)”是多個“書籍”組成的,“借閱記錄清單(brrow list)”是由多條“借閱記錄”組成的。這種組成關系使用于組合還有聚合關系呢?顯然,由于本系統的“書籍”是可以獨立于“書籍清單”而存在;“借閱記錄”也是可以獨立于“借閱記錄清單”而存在,是以使用聚合更合适一些。還可以發現“借閱記錄“和”“書籍”是關聯的,離開“書籍”,“借閱記錄”不存在意義。
為了反映和記錄這些類之間的關系,可以使用UML中的類圖将其記錄下來,如圖4-27所示。
圖4-27 最初的分析類模型
2.給關聯添加屬性
上圖沒有表示出關聯的細節資訊(關聯的屬性沒有辨別出來)。
(1)确定關聯的多重性
例如一本書可以有幾條借閱記錄,書籍清單指的是多少本書籍,這些問題需要進一步的進行多重性分析,并修改上面所示的類圖。
因為是個人藏書,是以每本書都是唯一的,沒有副本,要麼被借出,要麼未被借出,是以對于每一本書籍來說,要麼隻有一條借閱記錄,要麼沒有借閱記錄。
所有的書籍組成書籍清單,借閱記錄劉表是由所有的借閱記錄組成。
通過上面的分析,可以得到資訊補充的類圖,即可得到如圖4-28所示的類模型。
圖4-28 加入多重性的類圖
如果系統較大,可以以上面的類圖為基礎,把關聯度緊密的類合成一個包,以便更好的組織子系統。例如,在本例中可以将“書籍清單”、“書籍”、“計算機書籍”、"非計算機書籍“合成一個包,而将“借閱記錄”、“借閱記錄清單”合成另一個包。但本例比較簡單,類相對較少,是以無須進行這樣的合成。
(2)确定關聯的導航性——類圖中的諸如導航性,角色名,導出屬性,限定符及限制等進階屬性不是每個類模型都必須加入的。
在圖4-27中,隻有book和booklist之間的組合關系,brrowlrecord與borrowlist之間的組合關系、book與borrrecord之間的關聯關系,這三個關系可能存在導航性。
組合關系顯然已經将類的關系清晰化了,是以無須對其進行導航性描述。根據對需求的了解,book與borrowrecord之間,應該是一個雙向連結。因為,當浏覽書籍清單時,會希望看到某本書是否被借出;當有人歸還時,希望能從借閱記錄中關聯到book。
(3)确定限制
根據使用者需要,我們有兩個地方可以用限制來展現:一是book對象建立之後就不能被删除,隻能做修改,是以在book類邊上加上了一條用自由文本寫的限制。二是一本書要麼屬于計算機類,要門屬于非計算機類。是以要加一個“{xor}”限制。
(4)确定關聯的限定符
由于這個系統是“個人圖書管理系統”,是以特定的一本書隻有一本,是以隻能被借一次,是以對于一本書而言,隻有一個Recordid與其對應,是以将添加一個Recordid限定符。把限定符加入圖4-28中,再把類的職責(屬性和方法)加入到類圖後,得到的類圖,如圖4-29所示。
3.給類添加職責
當找到了反應問題域本質的主要類,并清理他們之間的關系之後,就可以為這些類添加相應的職責。類的職責包括以下兩個内容:類所維護的資訊(成員變量)和類提供的行為(成員方法)。
在本階段将主要的成員變量和成員方法辨別出來,以便更好的了解問題域。
書籍類:從需求描述中,可找到書名、類别、作者、出版社;同時從統計的需要中,可得知“定價”也是一個關鍵的成員變量。
書籍清單類:書籍清單就是全部的藏書清單,其主要的成員方法是新增、修改、查詢(按關鍵字查詢)、統計(按特定時限統計冊數與金額)。
借閱記錄類:借閱人(朋友)、借閱時間。
借閱記錄清單類:主要職責就是添加記錄(借出)、删除記錄(歸還)以及列印借閱記錄。
通過上面的分析,我們對這些概念類有了更深入的了解,可以重新修改類,将這些資訊加入原先的模型中。同時,把關聯的屬性加入類模型後,得到如圖4-29所示的類圖。
職責(屬性,方法)的添加是一個循序漸進的過程,在類分析,類設計時都是逐漸對類模型進行完善的。
圖4-29 加入限定符和限制的類圖
4.6 UML中類圖執行個體
接口:空心圓+直線(唐老鴨類實作了‘講人話’);
依賴:虛線+箭頭(動物和空氣的關系);
關聯:實線+箭頭(企鵝需要知道氣候才遷移);
聚合:空心四邊形+實線+箭頭(雁群和大雁的關系);
合成/組合:實心四邊形+實線+箭頭(鳥和翅膀的關系);
泛化/繼承:空心三角形+實線(動物和鳥的繼承關系);
實作:空心三角形+虛線(實作大雁飛翔的接口);
UML類圖
解釋UML類圖:
1.首先看“動物”矩形框,它代表一個類。該類圖分為三層,第一層顯示類的名稱,如果是抽象類就要用斜體顯示。第二層是類的特性,通常就是字段和屬性。第三層是類的操作,通常是方法和行為。
注意前面的符号,‘+’表示public, ‘—’ 表示private, ‘#’表示protected.
2.“飛翔”矩形框表示一個接口圖,它與類圖的差別主要是頂端有《interface》顯示,第一行是接口名稱,第二行是接口方法。接口還有另一種表示方法,俗稱棒棒糖表示法,就是唐老鴨類實作了“講人話”的接口。
interface IFly interface Ilanguage
{ {
void Fly(); void Speak();
} }
3.動物,鳥,鴨,唐老鴨他們之間都是繼承的關系,繼承關系用空心三角形+實作來表示。
4.“大雁”實作了“飛翔”接口。實作接口用空心三角形+虛線來表示。(注:下面的圖中應為空心三角形)
class Bird:Animal class WideGoose:IFly
//繼承動物類 //實作飛翔接口
5.企鵝與氣候有很大的關系,企鵝需要“知道”氣候的變化,需要“了解”氣候規律。當一個類“知道”另一個類時,可以用關聯(association)關系。關聯關系用實線箭頭來表示。
class Penguin :Bird
{
private Climate climate;//在企鵝Penguin中,引用到氣候Climate對象
}
6.“大雁”和“雁群”這兩個類。大雁是群居動物,每隻大雁都屬于一個雁群,一個雁群可以有多隻大雁。是以它們之間就滿足聚合(Aggregation)關系。聚合表示一種弱的“擁有”關系,展現的是A對象可以包含B對象,但B對象不是A對象的一部分。聚合關系用空心的菱形+ 實線箭頭表示。
class WideGooseAggregate
private WideGoose[] arrayWideGoose;
//在雁群WideGooseAggregate類中,有大雁數組對象arrayWideGoose
7.“鳥”和“翅膀”這兩個類。鳥和翅膀似整體和部分的關系,并且翅膀和鳥的生命周期是相同的,在這裡鳥和其翅膀就是合成關系。合成(composition)是一種強的“擁有”關系,展現了嚴格的部分和整體的關系,部分和整體的生命周期一樣。合成關系用實心的的菱形+實線箭頭來表示。另外,合成關系的連線兩端還有一個數字“1”和數字“2”,,這被稱為基數。表明這一端的類可以有幾個執行個體,很顯然,一個鳥應該有兩支翅膀。如果一個類可能有無數個執行個體,則就用“n”來表示。關聯關系,聚合關系也可以有基數的。
class Bird
private Wing wing;
public Bird()
wing=new Wing();
//在鳥Bird類中,初始化時,執行個體化翅膀Wing,它們之間同時生成
8.“動物”、“氧氣”與“水”之間。動物有幾大特征,比如有新陳代謝,能繁殖。而動物要有生命,需要氧氣,水以及食物等。也就是說動物依賴于氧氣和水。它們之間是依賴關系(Dependency),用虛線箭頭來表示。
abstract class Animal
public bolism(Oxygen oxygen,Water water)
小結
本章描述了模組化中最為核心的圖—類圖。詳細說明了類圖的概念,類的表示方法,類關系。
在此基礎上,講述了閱讀類圖的方法、技巧和相關知識。首先介紹了關系和多重性等基本内容,然後介紹了導航箭号,角色名稱,導出屬性,限定符和限制等增強部分的閱讀方法,最後還讨論了與類圖相關的進階概念。這些進階概念包括接口/抽象類、關聯類、模闆類、主動類、嵌套類等再分析、設計模型中經常會遇到的概念;另外還深入介紹了依賴關系和兩種類型的對象;最後通過執行個體分析詳細解讀了類圖的設計。