3.6 基于類的建模
基于類的建模表示了系統操作的對象、應用于對象間能有效控制的操作(也稱為方法或服務)、這些對象間(某種層級)的關系,以及已定義類之間的協作。基于類的分析模型的元素包括類和對象、屬性、操作、類-職責-協作者(CRC)模型、協作圖和包。
3.6.1 識別分析類
通過檢查需求模型開發的使用場景,對系統開發的用例進行“語法解析”,可以進行類的識別。其中,每個名詞或名詞詞組可以確定為類,并將這些名詞輸入到一個簡單的表中,標注出同義詞。如果要求某個類(名詞)實現一個解決方案,那么這個類就是解決方案空間的一部分;否則,如果只要求某個類描述一個解決方案,那么這個類就是問題空間的一部分。分析類表現為如下方式之一。
●外部實體(如其他系統、設備和人員),產生或使用基于計算機系統的信息。
●事物(如報告顯示、字母和信號),是問題信息域的一部分。
●偶發事件或事件(如所有權轉移或完成機器人的一組動作),在系統操作環境內發生。
●角色(如經理、工程師和銷售人員),由和系統交互的人員扮演。
●組織單元(如部門、組和團隊),與某個應用系統相關。
●場地(如制造車間或碼頭),建立問題的環境和系統的整體功能。
●結構(如傳感器、四輪交通工具和計算機),定義了對象的類或與對象相關的類。
此外,另一個重要的分類方法是指定義實體、邊界和控制類。
在分析模型中,分析師可以考慮每個潛在類是否應該使用以下這些特征。
1)保留信息。只有記錄潛在類的信息才能保證系統正常工作,這種分析過程中的潛在類是有用的。
2)所需服務。潛在類必須有一組可確認的操作,這組操作能用某種方式改變類的屬性值。
3)多個屬性。在需求分析過程中,焦點應在“主”信息上。事實上,只有一個屬性的類可能在設計中有用,但是在分析活動階段最好把它作為另一個類的某個屬性。
4)公共屬性。可以為潛在類定義一組屬性,這些屬性適用于類的所有實例。
5)公共操作。可以為潛在類定義一組操作,這些操作適用于類的所有實例。
6)必要需求。在問題空間中出現的外部實體,和任何系統解決方案運行時所必需的生產或消費信息,幾乎都被定義為需求模型中的類。
分析建模的一部分重要工作是分類,也就是將分析模型的各種元素(如用例、分析類等)以一種方式分類,分組打包后稱其為分析包,并取一個有代表性的名稱。
3.6.2 描述屬性
屬性描述了已經包含在需求模型中的類,定義并澄清類在問題空間環境下的實際含義。例如,如果建立一個系統來跟蹤職業棒球手的統計信息,類Player的屬性與用于職業棒球手的養老系統中的屬性是截然不同的。在前者,屬性是與名字、位置、平均擊球次數、擔任防守百分比、從業年限及比賽次數等相關的;在后者,某些屬性具有相同的含義,另外一些屬性將被替換,例如,平均工資、享受優惠權后的信用、所選的養老計劃和郵件地址等。
為了給分析類開發一個有意義的屬性集合,軟件工程師應該研究用例并選擇那些合理“屬于”類的“事物”。此外,每個類都應回答如下問題:什么數據項(組合項和/或者基本項)能夠在當前問題環境內完整地定義這個類?
3.6.3 定義操作
操作定義了某個對象的行為。盡管存在很多類型的操作,但通常可以粗略地劃分為4種類型:①以某種方式操作數據(如添加、刪除、重新格式化和選擇);②執行計算的操作;③請求某個對象的狀態操作;④監視某個對象發生某個控制事件的操作。這些功能通過在屬性和/或相關屬性上的操作實現。因此,操作必須“理解”為類的屬性和相關屬性的性質。
在第一次迭代要導出一組分析類的操作時,可以再次研究處理敘述(或用例),并合理地選擇屬于該類的操作,為此可以再次進行語法解析并分離動詞。這些動詞中的一部分將是合法的操作,并能夠很容易地連接到某個特定類。
另外,對于語法分析,分析師能通過考慮對象間所發生的通信獲得對其他的操作更為深入的了解。對象通過傳遞信息與另一個對象通信。在繼續對操作進行說明之前,探測到了更詳實的信息。
3.6.4 類-職責-協作者建模
類-職責-協作者(Class-Responsibility-Collaborator,CRC)建模提供了一個簡單方法,可以識別和組織與系統或產品需求相關的類。CRC模型實際上是表示類的標準索引卡片的集合。這些卡片分為3部分:頂部寫類名,卡片主體左側部分列出類的職責,右側部分列出類的協作者。
事實上,CRC模型可以使用真的或虛擬的索引卡,意圖是開發有組織表示的類。職責是和類相關的屬性和操作。簡單地說,職責就是“類所知道或能做的任何事”。協作者是提供完成某個職責所需要信息的類。通常,協作意味著信息請求或某個動作請求。
FloorPlan類的一個簡單CRC索引卡如圖3-13所示。CRC卡上所列出的職責只是初步的,可以添加或修改。在職責欄右邊的Wall和Camera是需要協作的類。
1.類
類的分類可以通過如下分類方式進行擴展。
●實體類,也稱為模型或業務類,是從問題說明中直接提取出來的(例如FloorPlan和Sensor)。這些類一般代表保存在數據庫中和貫穿應用程序(除非被明確刪除)的事物。
圖3-13 CRC模型索引卡
●邊界類,用于創建用戶可見的和在使用軟件時交互的接口(如交互屏幕或打印的報表)。實體類包含對用戶來說很重要的信息,但是并不顯示這些信息。設計邊界類的職責是管理實體對象對用戶的表示方式。例如,一個被稱為CameraWindow的邊界類負責顯示SafeHome系統監視攝像機的輸出。
●控制類自始至終管理著“工作單元”。也就是說,設計控制類可以管理:①實體類的創建或更新;②當邊界類從實體對象獲取信息后的實例化;③對象集合間的復雜通信;④對象間或用戶和應用系統間交換數據的確認。通常直到設計開始時才開始考慮控制類。
2.職責
在給類分配職責時建議考慮以下5個指導原則。
1)智能系統應分布在所有類中以求最好地滿足問題的需求。每個應用系統都包含一定程度的智能,也就是系統內所含有它知道的及所能完成的。智能在類中可以有多種分布方式。建模時可以把“不靈巧”類(幾乎沒有職責的類)作為一些“靈巧”類(有很多職責的類)的從屬。盡管該方法使得系統中的控制流簡單易懂,但缺點是:把所有的智能集中在少數類,使得變更更為困難;將會需要更多的類,因此需要更多的開發工作。
如果智能系統更平均地分布在應用系統的所有類中,每個對象只了解和執行一些事情(通常是適度集中),并提高系統的內聚性,這將提高軟件的可維護性,并減少變更的副作用影響。
為了確定是否恰當地分布了智能系統,應該評估每個CRC模型索引卡上標記的職責,以確定某個類是否應該具有超長的職責列表。出現這種情況就表明智能太集中(可能需要將一個類分成多個類或子系統,以便更有效地分布智能)。此外,每個類的職責應表現在同一抽象層上。例如在聚合類CheckingAccount操作列表中,評審人員注意到兩項職責:賬戶余額和已結算的支票。第一個操作的職責意味著復雜的算術和邏輯過程;第二個操作的職責是指簡單的辦事員活動。既然這兩個操作不是相同的抽象級別,已結算的支票應該被放在CheckEntry的職責中,這是由聚合類CheckingAccount壓縮得到的一個類。
2)每個職責的說明應盡可能具有普遍性。這條指導原則意味著應在類的層級結構的上層保持職責(屬性和操作)的通用性(因為它們更有一般性,將適用于所有的子類)。
3)信息和與之相關的行為應放在同一個類中。這實現了面向對象原則中的封裝,數據和操作數據的處理應包裝在一個內聚單元中。
4)某個事物的信息應局限于一個類中而不要分布在多個類中。通常應由一個單獨的類負責保存和操作某特定類型的信息,這個職責不應由多個類分擔。如果信息是分布式的,軟件將變得更加難以維護,測試也會面臨更多挑戰。
5)適合時,職責應由相關類共享。很多情況下,各種相關對象必須在同一時間展示同樣的行為。例如,考慮一個視頻游戲,必須顯示如下類:Player、PlayerBody、PlayerArms、PlayerLegs和PlayerHead,每個類都有各自的屬性(如position、orientation、color和speed),并且所有這些屬性都必須在用戶操縱游戲桿時更新和顯示。因此,每個對象必須共享職責update()和display()。Player知道在什么時候發生了某些變化并且需要update()操作,它和其他對象協作獲得新的位置或方向,但是每個對象控制各自的顯示。
3.協作
類有一種或兩種方法實現其職責:①類可以使用自身的操作控制各自的屬性,從而實現特定的職責;②一個類可以和其他類協作。
協作是以客戶職責實現的角度表現從客戶到服務器的請求。協作是客戶和服務器之間契約的具體實現。如果為了實現某個職責需要發送任何消息給另一個對象,就說這個對象和其他對象有協作。單獨的協作是單向流,即表示從客戶到服務器的請求。從客戶的角度看,每個協作都和服務器的某個特定職責實現相關。
要識別協作可以通過確認類本身是否能夠實現自身的每個職責。如果不能實現每個職責,那么需要和其他類交互,因此就要有協作。
為幫助識別協作者,分析師可以檢查類之間的3種的通用關系:①is-part-of(是……一部分)關系;②has-knowledge-of(有……的知識)關系;③depends-upon(依賴)關系。在下面的段落中將簡單地分別說明這3種通用關系。
屬于某個聚合類一部分的所有類可通過is-part-of關系和聚合類連接。考慮前面提到的視頻游戲中所定義的類,PlayerBody是Player的一部分,PlayerArms、PlayerLegs和PlayerHead也類似。在UML中,使用如圖3-14所示的聚合方式表示這些關系。
圖3-14 復合聚合類
當一個類必須從另一個類中獲取信息時,就建立了has-knowledge-of關系。
所有情況下,把協作類的名稱記錄在CRC模型索引卡上,緊靠在協作的職責旁邊。因此,索引卡包含一個職責列表,以及相關的能夠實現這些職責的協作(參考圖3-13)。
當開發出一個完整的CRC模型時,干系人可以使用如下方法評審模型。
①所有參加(CRC模型)評審的人員拿到一部分CRC模型索引卡。拆分協作卡片(也就是使每個評審員不得有兩張存在協作關系的卡片)。
②分類管理所有的用例場景(以及相關的用例圖)。
③評審組長細致地閱讀用例。當評審組長看到一個已命名的對象時,給擁有相應類索引卡的人員一個令牌。
3.6.5 關聯和依賴
在很多例子中,兩個分析類以某種方式相互聯系著,就如同彼此相互聯系的兩個數據對象。在UML中,這些聯系被稱為關聯(associations)。在某些情況下,關聯可以更進一步地指出多樣性,其中“一個或多個”使用1..表示,“0或多個”使用0..表示。在UML中,星號表示范圍無上界。其他的多樣性關聯(一對一、一對多、多對多、一對某指定上下限的范圍等)可以標識為關聯的一部分。
在很多事例中,兩個分析類之間存在客戶-服務器關系。這種情況下,客戶類以某種方式依賴于服務器類并且建立了依賴關系。依賴是由一個構造型(stereotype)定義的。在UML中,構造型是一個“可擴展機制”,允許軟件工程師定義特殊的建模元素,這些建模元素的語義是由用戶自定義的。在UML中,構造型用一對尖括號表示(如<<stereotype>>)。