作爲OOAD中的第二步,概念模型的識別顯得比用例識別更加困難。
爲什麼要創建領域模型
降低與OO建模之間的表示差異。
領域層軟件類的名稱要源於領域模型中的名稱,以使對象具有源於領域的信息和職責。
打個比方,你可以用一長串0和1來表示“薪水冊”,可是這種軟件表示與我們腦中的薪水冊領域模型之間存在巨大的差異,這將影響我們對軟件的理解和修改。而OO建模則可以減小這一差異。
如何創建領域模型
那又如何創建領域模型呢?
可以通過以下三個步驟:
- 尋找概念類
- 將其繪製爲UML類圖中的類
- 添加關聯
- 添加屬性
如何找到概念類
1)重用和修改現有的模型。
這是首要、最佳且最簡單的辦法。可以從已發佈的領域模型和書籍中獲得。
2)使用分類列表
示例:
(圖二)
3)確定名詞列表
在對領域的文本性描述中識別名詞和名詞短語,將其作爲候選的概念類或屬性。
缺點:自然語言的不精確性,不同名詞短語可能表示同一概念類或屬性,此外可能還有歧義。
建議與概念類分類列表一同使用。
在實踐中,在發現概念類時,一般直接爲其繪製UML類圖。
瞭解了幾種識別概念類的方法,我們接下來討論過程中可能出現的問題。
1)最常見錯誤:把應該是概念類的事物表示爲屬性。
準則:如果我們認爲某概念類X不是現實世界中的數字或文本,那麼X可能是概念類而不是屬性。
考慮一下航空預定領域。destination應該作爲Flight的屬性,還是作爲單獨的概念類Airport?
(圖三)
在現實世界裏,目的地機場不會被看作是數字或文本,而是一佔據大規模空間的事物。因此,Airport應該是個概念,而不是屬性。
2)缺少描述類
描述類包含描述其他事物的信息。例如,ProductDescription記錄Item的價格、圖片和文字描述。
爲什麼使用描述類?
假設:雀巢咖啡,大受歡迎,銷售一空。這就意味着雀巢咖啡的所有Item實例都從計算機存儲器中被刪除。這時如果有人問:雀巢咖啡多少錢一盒?那將沒法回答。因爲價格是記錄在實例上的,而這些實例都已經被刪除。由此可以看出,需要其他事物來記錄雀巢咖啡的描述(規格說明)。
(圖四)
又比如,虹橋機場每天有很多航班,同一架飛機有多個航線,但其一架飛機只有一個飛機號碼。如果僅僅有兩個概念類Flight和Airport,假設有一天天降大霧,所有航班取消,我們刪除了所有Flight記錄。這時如果我們想知道是否存在號碼爲12345的一架飛機,那我們將無法查到。由此可以看出,我們還需要一個描述類FlightDescription。
何時需要?
1. 需要有關商品或服務的描述,獨立於任何商品或服務的現有實例。
2. 刪除其所描述事物(如Item)的實例後,導致信息丟失,而這些信息是需要維護的,但是被錯誤地與所刪除的事物關聯起來。
3. 減少冗餘或重複信息。
關聯
什麼是關聯?
關聯是類(類的實例)之間的關係,表示有意義和值得關注的連接。
(圖五)
關聯名
關聯名來描述一個關聯的本質。
角色(Role)
用來描述離角色名較近一端的類在另一端的類面前所呈現的面貌。
何時表示關聯?
1. 如果存在需要保持一段時間的關係,將這種語義表示爲關聯(“需要記住”的關聯)。
2. 從常見關聯列表中派生的關聯。
準則:要避免在領域模型中加入太多的關聯。
在領域建模過程中,關聯不是關於數據流、數據庫外鍵聯繫、實例變量或軟件方案中的對象連接的語句;關聯聲明的是針對現實領域從純概念角度看有意義的關係。
在UML中如何對關聯命名
以“類名-動詞短語-類名”的格式爲關聯命名,其中的動詞短語構成了可讀的和有意義的順序。
圖五對應於:VideoStore Stocks Video
多重性
多重性定義了類A有多少個實例可以和類B的一個實例關聯。(見圖五)
多重性的值表示在特定時刻(而不是在某個時間跨度內)有效關聯的實例數量。
(圖六)
多重性是和語境有關的。
兩個類之間的多重關聯:
(圖七)
常見關聯列表
(圖八)
一個例子
屬性
在UML中,一個屬性的完整語法是:visibility name : type multiplicity = default {property-string},即可見的名稱 : 類型 = 默認值 {性質}。
什麼是屬性?
屬性是對象的邏輯數據值。
何時展示屬性?
當需求(例如,用例)建議或暗示需要記住信息時,引入屬性。
(圖九)
導出屬性(derived attribute):可以由其他信息導出的屬性。
準則:大部分屬性類型應該是“簡單”數據類型,例如數字和布爾。通常,屬性的類型不應該是複雜的領域概念,例如Sale或AirPort。
準則:領域模型中屬性的類型更應該是數據類型。
準則:通過關聯而不是屬性來表示概念類之間的關係。
(圖十)
領域模型是概念透視圖,不是軟件透視圖。在設計模型中,屬性可以是任何類型。
準則:任何屬性都不表示外鍵。
(圖十一)