類的UML表示
類的命名儘量套用領域中的術語,應明確、無岐義,以利於相互交流和理解。類的屬性、操作中的可見性使用+、#、-分別表示public、protected、private。
類之間的關係
類之間的關係是類圖中比較複雜的內容。有關聯、聚合、組合、泛化、依賴。
關聯:是模型元素之間的一種語義联系,是類之間的一種很弱的聯繫。關聯可以有方向,可以是單向關聯,也可以是雙向關聯。可以給關聯加上關聯名來描述關聯的作用。關聯兩端的類也可以以某種角色參與關聯,角色可以具有多重性,表示可以有多少個對象參與關聯。可以通過關聯類進一步描述關聯的屬性、操作以及其他信息。關聯類通過一條虛線與關聯連線。對於關聯可以加上一些約束,以加強關聯的含義。如下圖所示:
聚合是一種特殊的關聯,聚合表示整體與部分的關係。通常在定義一個整體類後,再去分析這個整體類的組成結構。從而找出一些組成類,該整體類和組成類之間就形成了聚合關係。例如艦隊是由一系列的艦船組成。需求描述中“包含”、“組成”、“分為….部分”等詞常意味著聚合關係。
組合也是一種特殊的關聯,也表示類之間整體和部分的關係,但是組合關係中部分和整體具有統一的生存期。一旦整體對象不存在,部分對象也將不存在。部分對象與整體對象之間具有共生死的關係。
聚合和組合的區別:聚合關係是“has-a”關係,組合關係是“contains-a”關係;聚合關係表示整體與部分的關係比較弱,而組合比較強;聚合關係中代表部分事物的對象與代表聚合事物的對象的生存期無關,一旦刪除了聚合對象不一定就刪除了代表部分事物的對象。組合中一旦刪除了組合對象,同時也就刪除了代表部分事物的對象。
泛化定義了一般元素和特殊元素之間的分類關係,類之間的這種泛化關係也就是繼承關係。泛化關係是“a-kind-of”關係,定義一般元素和特殊元素之間的分類關係。下圖是一個泛化關係的例子。
有兩個元素如果修改X的定義可能會導致對Y的定義,則認為Y依賴X。依賴關係可能由各種原因引起,如一個類向另一個類傳送訊息,或者一個類是另一個類的數據成員類型,或者一個類是另一個類的操作的參數類型等。有時依賴關係和關聯關係比較難區分。如果類A和類B有關聯關係,它們之間必然有依賴關係。如果兩個類之間有關聯關係時不用再表示出這兩個類之間的依賴關係。
建立類圖
在軟體開發不同階段使用的類圖具有不同的抽象層次,即概念層、說明層、和實現層。使用UML進行套用建模也應該是一個疊代的過程,所以我們應該建立一個類圖的層次的概念。
概念層類圖描述套用領域中的概念,這些概念與實現它們的類有聯繫。通常沒有直接的映射關係。畫概念層類圖時很少考慮或不考慮實現問題,因此概念層類圖應獨立於具體的程式語言。下面是一個概念層類的表示。
說明層類圖。此時我們考察的是類的接口部分,而不是實現部分。這個接口可能因為實現環境、運行特性等有多種不同的實現。下面是一個說明層類的表示。
實現層類圖才真正考慮類的實現問題,提供實現的細節。此時的類的概念才應該是真正的嚴格意義上的類。它揭示了軟體實體的構成情況。實現層的類是最常用的,在很多的時候說明層的類更有助於人們對軟體的理解。
UML的最終目標是識別出所有必須的類,並分析這些類之間的關係,類的識別貫穿於整個建模過程,分析階段主要識別問題域相關的類,在設計階段需要加入一些反映設計思想、方法的類以及實現問題域所需要的類,在編碼實現階段,因為語言的特點,可能需要加入一些其他的類。
建立類圖的步驟:
(1)研究分析問題領域確定系統需求。
(2)確定類,明確類的含義和職責、確定屬性和操作。
(3)確定類之間的關係。
類的識別是一個需要大量技巧的工作,尋找類的一些技巧包括:名詞識別法;根據用例描述確定類;使用CRC分析法;根據邊界類、控制類、實體類的劃分來幫助分析系統中的類;參考設計模式確定類;對領域進行分析或利用已有領域分析結果得到類;利用RUP中如何在分析和設計中尋找類的步驟。
1. 名詞識別法:
這種方法的關鍵是識別系統問題域中的實體。對系統進行描述,描述應該使用問題域中的概念和命名,從系統描述中標識名詞及名詞短語,其中的名詞往往可以標識為對象,複數名詞往往可以標識為類。
2. 從用例中識別類:
用例圖實質上是一種系統描述的形式,自然可以根據用例描述來識別類。針對各個用例,可以提如下的問題輔助識別:
用例描述中出現了那些實體?
用例的完成需要哪些實體合作?
用例執行過程中會產生並存儲哪些信息?
用例要求與之關聯的每個角色的輸入是什麼?
用例反饋與之關聯的每個角色的輸出是什麼?
用例需要操作哪些硬設備?
在面向對象套用中,類之間傳遞的信息數據要么可以映射到傳送方的某些屬性,要么該信息數據本身就是一個對象。綜合不同的用例識別結果,就可以得到整個系統的類,在類的基礎上,我們又可以分析用例的動態特性來對用例進行動態行為建模。
3. 使用CRC分析法:
CRC(Class,Responsibilities,Collaboration)卡的最大價值在於把人們從思考過程模式中脫離出來,更充分的專注於對象技術。CRC卡允許整個項目組對設計做出貢獻。參與系統設計的人越多,能夠收集到的好主意也就越多。因為CRC會議是大家全力參與的,通常只需要很少的有類名的卡片,實際上沒有寫出完整的卡片。CRC會議進行中,一些人模擬系統和對象交流,把訊息傳給其他的對象。通過一步步處理,問題很容易地被解決。它由三部分組成:類(Class)、職責(Responsibility)、協作(Collaborator)。下面是一個CRC卡的示例:
類名 | |
職責1 | 職責1的協作 |
職責2 | 職責2的協作 |
…… | …… |
職責是類需要知道或做的任何事物。這些職責是類自身所知的知識,或類在執行時所需的知識。協作是指為獲取訊息,或協助執行活動的其他類。創建CRC模型需要下面的步驟。
1) 建立團隊,包括客戶、設計人員、分析人員和一個導引者。如果沒有那么多人,那么可以是客戶和你自己兩個人。
2) 找出需求中存在的名詞和名詞詞組,特別注意複數(通常是集合),他們對應的單數才是。把你第一次想到的所有概念都寫在白板或紙上。不管看起來這些概念是如何荒謬,把他們都寫下來。
3) 篩選。把對象分為三類,核心對象(必須首先實現),可選的(目前不能確定),以及不需要的對象。這之前最好確定一下你的項目範圍。某些不屬於本項目範圍的對象可以使用輕量的adapter或proxy實現。這裡可以加入對分析、設計模式的考慮和套用。
4) 建卡。取出CRC卡,把核心類寫在每一張卡上,把可選的類和排除的類分別寫在不同的紙上。
5) 角色扮演。最好是一個團隊執行,一個人很難做。每個人負責幾個類。對每一個Use case其中的情景。導引者指定從某一個人的類開始,某一個人看一看自己能夠獨立完成,如果不能完成,大家看一看手中的類,誰能完成,就站起來,宣布自己能夠完成,以致繼續這個過程,每個人完成自己的職責就坐下。在這過程中不斷修改類的責任,並寫下協作者的名字。
4. 根據邊界類、控制類、實體類幫助分析系統中的類
UML中類有三種主要的版型:邊界類、控制類和實體類。引入邊界類、控制類及實體類的概念有助於分析和設計人員確定系統中的類。
邊界類位於系統與外界的交界處,窗體、報表、以及表示通訊協定的類、直接與外部設備互動的類、直接與外部系統互動的類等都是邊界類。通過用例圖可以確定需要的邊界類,每個Actor/Use Case對至少要一個邊界類,但並非每個Actor/Use Case對要唯一的邊界類。
實體類保存要放進持久存儲體的信息。持久存儲體就是資料庫、檔案等可以永久存儲數據的介質。實體類可以通過事件流和互動圖發現。通常每個實體類在資料庫中有相應的表,實體類中的屬性對應資料庫表中的欄位。
控制類是控制其他類工作的類。每個用例通常有一個控制類,控制用例中的事件順序,控制類也可以在多個用例間共用。其他類並不向控制類傳送很多訊息,而是由控制類發出很多訊息。
5. 領域進行分析
建立類圖的過程就是對領域及其解決方案的分析和設計過程。類的獲取是一個依賴個人創造力的過程,有時需要和領域專家合作,對研究領域進行仔細分析,抽象出領域中的概念,定義其含義及相互關係,分析出系統類,並用領域中的術語為類命名。領域分析是:通過對某一領域中的已有套用系統、理論、技術、開發歷史等的研究,來標識、收集、組織、分析和表示領域模型及軟體體系結構的過程,並得到結果。
使用類圖
類圖幾乎是所有面向對象方法的支柱,應該如何使用類圖呢?以下提供了一些使用類圖的一些建議。
不要試圖在項目的初始階段使用所有的符號,首先應該從簡單概念開始。比如類的關係等等,在需要的時候才使用。在項目的不同開發階段,應該使用不同的觀點來畫類圖。如果處於分析階段應該畫概念層類圖,當開始著手軟體設計時,應該畫說明層類圖,當針對某個特定的技術實現時應該畫實現層類圖。不要為每個事物都畫一個模型,應該把精力放在關鍵的領域。使用類圖的最大危險是過早的陷入實現的細節,為了避免這個問題,應該將重點放在概念層和說明層。