複製鏈接
請複製以下鏈接發送給好友

領域模型

鎖定
領域模型是對領域內的概念類或現實世界中對象的可視化表示。又稱概念模型、領域對象模型、分析對象模型。它專注於分析問題領域本身,發掘重要的業務領域概念,並建立業務領域概念之間的關係。
中文名
領域模型
外文名
Domain Model
概    念
對領域內概念類的可視化表示

領域模型概念

業務對象模型(也叫領域模型 domain model)是描述業務用例實現的對象模型。它是對業務角色和業務實體之間應該如何聯繫和協作以執行業務的一種抽象。業務對象模型從業務角色內部的觀點定義了業務用例。該模型為產生預期效果確定了業務人員以及他們處理和使用的對象(“業務類和對象”)之間應該具有的靜態和動態關係。它注重業務中承擔的角色及其當前職責。這些模型類的對象組合在一起可以執行所有的業務用例 [1] 

領域模型核心元素

業務角色顯示了一個人承擔的一系列職責。業務實體表示使用或產生的可交付工件、資源和事件。業務用例實現顯示了協作的業務角色和業務實體如何執行某個工作流程。使用以下幾種圖來記錄業務用例實現: 圖顯示參與的業務角色和業務實體。活動圖,其中泳道顯示業務角色的職責,而對象流顯示如何在工作流程中使用業務實體。 序列圖描述業務角色和業務主角之間交互的詳細情況,並顯示如何在業務用例執行過程中訪問業務實體。
領域模型 領域模型
業務對象模型將結構的概念和行為的概念結合了起來。
它是一個紐帶工件,用於對業務關係進行清晰的表述,表述方式與軟件開發人員的思考方式類似,同時仍保留一些純粹的業務內容。將我們所知道的有關業務的信息按照對象、屬性和職責進行了合併。
它探索業務領域知識的本質,所採用的方式使我們能夠從對業務問題的思考轉變到對軟件應用程序的思考上來。
它是一種確定需求的方法,使需求能夠為待建信息系統使用,並得到該系統的支持。
確定業務對象定義、對象間關係、對象名稱和對象間關係名稱的流程使我們能夠以一種能被業務領域專家理解和驗證的精確方式來表達業務領域知識。

領域模型命名

對每個業務角色和實體進行命名,要求名稱能夠表示對象的職責。
一個好的名稱通常是名詞或動詞的名詞形式, 每個名稱都必須是唯一的。避免使用發音或拼寫類似的詞以及同義詞作為名稱,可能需要用好幾個單詞來組成一個明確的、無需額外説明的名稱。

領域模型對象

當您研究參與業務中不同用例的業務角色和業務實體時,可能會發現某些對象如此相似,以致於實際上是一個類。即使不同的業務用例沒有相同的要求,類是之間也可能相似到足以被視為一個相同現象的程度。如果是這種情況,您應該將相似的類合併在一起。這就產生了一個業務角色或業務實體,它擁有足以滿足不同業務用例要求的關係、屬性和操作。
因此,多個業務用例可以對同一個類有不同的要求。對於業務角色來説,如果有些僱員有能力擔當所描述的一組角色,那麼同樣還要有一些比較靈活可以勝任多個職位的僱員。這會使您的業務更加靈活 [2] 

領域模型模型

在業務對象模型中,業務角色代表僱員將擔當的角色,而業務實體則代表僱員將處理的對象。一方面,可以使用業務對象模型來確定業務僱員將如何進行交互,以產生業務主角所期望的結果。另一方面,系統用例模型和設計模型指定了業務的信息系統。
業務建模和系統建模解決不同的問題,其抽象程度也不一樣。所以一般而言,信息系統不應該直接出現在業務模型中。
另一方面,僱員作為業務角色來使用信息系統,實現相互之間的通信、與主角的通信以及對業務實體信息進行訪問。所有的鏈接、關聯關係或屬性都有某個潛在的信息系統對其進行支持。
這兩類建模環境有以下關係:
作為特定業務角色的僱員與信息系統的一個系統主角相對應。如果建立的信息系統使該僱員在業務用例中的所有工作都得到一個系統用例的支持,則他最有可能得到最好的支持。 另外,如果業務用例規模大、生存期長或者合併了多個獨立領域中的工作,信息系統用例將可以支持業務角色的操作。 僱員工作的對象(建模為業務實體)常在信息系統中得到表現。在信息系統的對象模型中,這些業務實體作為實體類出現。業務實體之間的關聯關係和聚合關係常常使設計模型中實體類之間產生對應的關聯關係和聚合關係。 因此,系統用例訪問並操作設計模型中的實體類,這些實體類代表由被支持業務用例訪問的業務實體。最後,直接使用業務信息系統的業務主角也成為信息系統的系統主角。 當確定對支持業務的信息系統的需求時,這些關係十分關鍵。

領域模型主角

有時候,一個業務的僱員與另一個業務的僱員使用其他業務的信息系統進行聯繫。從建模後業務的角度來看,這個信息系統就是一個業務主角。
示例: 某個軟件開發人員努力去理解他所負責的產品中出現的問題。為了瞭解問題是否源於他所使用的編程工具,他與供應商的萬維網服務器聯繫,並仔細研究編程工具當前版本中已知問題的列表。通過這種方式,業務角色“軟件開發人員”與業務角色“提供商的萬維網服務器”進行交互。

領域模型定位

通常的做法是不在業務對象模型中對信息系統進行明確建模,因為信息系統只是業務角色所使用的工具而已。但當業務的信息系統被客户直接使用時,這種做法就不合適了。如果這個交互是業務服務的主要部分,您可能會出於商業上重要性的考慮而希望在業務對象模型中將其展示出來。電話銀行業務就是此類信息系統的一個很好的例子。
從業務建模的觀點來看,建議使用以下方法:
將信息系統看做一個和主角交互的完全自動化的業務角色。如果信息系統和任何其他業務角色或業務實體相關,則考慮使用鏈接或關聯關係來説明這種關係。系統可能會向某個業務角色通知其進度,或者使用與某個業務實體相關的信息。 簡單地説明業務角色,同時列出代表業務對象模型中信息系統的服務。在信息系統模型中對信息系統和其環境的所有細節和特徵進行建模。引入一個命名約定,這樣可以容易地在業務角色中確定那些完全自動化的業務角色,例如,一個前綴或後綴,如“自動<業務角色名稱>”或“<業務角色名稱>(IT 系統)”。您甚至可以使用一個特殊的圖標來定義構造型 [3] 

領域模型特徵

總的來看,業務角色和業務實體執行業務用例中描述的所有活動,絕不多一點,也絕不少一點。業務對象模型有效、全面地對組織進行了展示。

領域模型實例

舉一個簡單的例子來説明如何進行領域模型設計。
假如我們要為一個小賣店設計一套進銷存系統,她為我們提供的業務描述是這樣的:每天凌晨從布吉農批市場買蘋果、梨、葡萄、橘子、香蕉、荔枝、核桃等等,反正哪些好賣她就買回來賣。葡萄、荔枝不能長久保留,一般要當天賣出去…。
針對上面這段業務描述,我們怎麼進行領域模型設計?我給出以下幾個步驟來完成領域模型設計。
總結業務描述中的名詞
首先建一個名詞表,把涉及到的名詞列出來:
序號名詞備註;
1. 布吉農批市場
2. 買東西的人是一個隱含的名詞,每天凌晨從農批市場拿貨
3. 蘋果
4. 梨
5. 葡萄
6. 橘子
7. 香蕉
8. 荔枝
9. 核桃
10. 顧客是一個隱含的名詞,買回來賣的對象
11. 凌晨、當天時間名詞,與實體及角色無關
這個名詞列表包括了業務的行為主體:角色,以及業務過程中的操作實體:模型,對我們接下來的用例描述、領域模型分析、需求分析很有幫助。當然這個名詞列表需要經過進一步分析提煉,成為領域模型
確定業務實體
序號名詞描述;
1. 布吉農批市場不是本業務的一個實體
2. 買東西的人是本業務的一個角色
3. 蘋果是一個實體
4. 梨是一個實體
5. 葡萄是一個實體
6.橘子是一個實體
7. 香蕉是一個實體
8. 荔枝是一個實體
9. 核桃是一個實體
10. 顧客是本業務的一個角色
11. 凌晨、當天時間名詞,與實體及角色無關
經過分析,我們得出的實體是蘋果、梨、葡萄、橘子、香蕉、荔枝、核桃,這些是不是模型呢?應該説還不是,還要經過進一步分析:在我們分析的業務領域內,它們有沒有共性?蘋果、梨、葡萄、橘子、香蕉、荔枝屬於水果,核桃屬於乾果,它們都是果品的一個具體實例。而在水果中葡萄和荔枝屬於不宜保存水果,通過這樣進一步的分析得出如下的領域模型:
果品進銷存領域模型
這個領域模型不但能反映當前的經營實體,同時給我們需求分析人員和系統功能提供了一定的擴展視野:將來會不會經營食品,短期保持水果採取什麼利潤空間來促銷,長期保存的水果會不會因為保存成本而導致利潤下降。

領域模型關係

認為領域模型它是一個分析模型,幫助系統分析人員、用户認識現實業務的工具,描述的是業務中涉及到的實體及其相互之間的關係,它是需求分析的產物,與問題領域相關。領域模型是需求分析人員與用户交流的有力工具,是需求分析人員與用户共同理解的概念,是彼此之間交流的語言。而數據模型是系統設計、實現的一部分,描述的是對用户需求在數據結構上的實現,僅此而已。當然數據模型中的概念模型設計與領域模型類似,缺乏的是實體之間更廣泛的關係描述。
通常大家會考慮數據怎麼存放的問題,我的理解是領域模型設計期間不用考慮數據的存放問題,只考慮業務描述中涉及的實體以及實體之間的關係。
實體之間的關係,很多書都講了,無非是泛化、依賴和關聯,關聯又分了一般關聯、聚合、組合等等,我這裏就不列了。

領域模型設計步驟

領域模型設計是需求分析的關鍵步驟。它幫助用户及需求分析人員建立業務概念,確定用户業務的問題域,系統涉及的業務範圍等等。
領域模型設計的步驟為:
1. 從業務描述中提取名詞;
2. 從提取出來的名詞中總結業務實體,區分名詞中的屬性、角色、實體、實例,形成問題域中操作實體的集合;
3. 從業務實體集合中抽象業務模型,建立問題域的概念(例如在前面的例子中,我們把容易變質的水果稱之為“短期保持水果”,當然也可以是其它説法,只要能跟用户達成共識即可);
4. 用UML提供的方法和圖例進行領域模型設計、確定模型之間的關係 [4] 

領域模型種類

領域模型失血模型

簡單來説,就是domain object只有屬性的getter/setter方法,沒有任何業務邏輯。

領域模型貧血模型

簡單來説,就是domain ojbect包含了不依賴於持久化的領域邏輯,而那些依賴持久化的領域邏輯被分離到Service層。Service(業務邏輯,事務封裝) --> DAO ---> domain object
這種模型的優點:
1、各層單向依賴,結構清楚,易於實現和維護
2、設計簡單易行,底層模型非常穩定
這種模型的缺點:
1、domain object的部分比較緊密依賴的持久化domain logic被分離到Service層,顯得不夠OO
2、Service層過於厚重

領域模型充血模型

充血模型和第二種模型差不多,所不同的就是如何劃分業務邏輯,即認為,絕大多業務邏輯都應該被放在domain object裏面(包括持久化邏輯),而Service層應該是很薄的一層,僅僅封裝事務和少量邏輯,不和DAO層打交道。
Service(事務封裝) ---> domain object <---> DAO
這種模型的優點:
1、更加符合OO的原則
2、Service層很薄,只充當Facade的角色,不和DAO打交道。
這種模型的缺點:
1、DAO和domain object形成了雙向依賴,複雜的雙向依賴會導致很多潛在的問題。
2、如何劃分Service層邏輯和domain層邏輯是非常含混的,在實際項目中,由於設計和開發人員的水平差異,可能導致整個結構的混亂無序。
3、考慮到Service層的事務封裝特性,Service層必須對所有的domain object的邏輯提供相應的事務封裝方法,其結果就是Service完全重定義一遍所有的domain logic,非常煩瑣,而且Service的事務化封裝其意義就等於把OO的domain logic轉換為過程的Service TransactionScript。該充血模型辛辛苦苦在domain層實現的OO在Service層又變成了過程式,對於Web層程序員的角度來看,和貧血模型沒有什麼區別了 [5] 

領域模型脹血模型

基於充血模型的第三個缺點,有同學提出,乾脆取消Service層,只剩下domain object和DAO兩層,在domain object的domain logic上面封裝事務。
domain object(事務封裝,業務邏輯) <---> DAO
似乎ruby on rails就是這種模型,他甚至把domain object和DAO都合併了。
該模型優點:
1、簡化了分層
2、也算符合OO
該模型缺點:
1、很多不是domain logic的service邏輯也被強行放入domain object ,引起了domain ojbect模型的不穩定
2、domain object暴露給web層過多的信息,可能引起意想不到的副作用。
在這四種模型當中,失血模型和脹血模型應該是不被提倡的。而貧血模型和充血模型從技術上來説,都已經是可行的了。但是我個人仍然主張使用貧血模型。其理由:
1、參考充血模型第三個缺點,由於暴露給web層程序拿到的還是Service Transaction Script,對於web層程序員來説,底層OO意義喪失了。
2、參考充血模型第三個缺點,為了事務封裝,Service層要給每個domain logic提供一個過程化封裝,這對於編程來説,做了多餘的工作,非常煩瑣。
3、domain object和DAO的雙向依賴在做大項目中,考慮到團隊成員的水平差異,很容易引入不可預知的潛在bug。
4、如何劃分domain logic和service logic的標準是不確定的,往往要根據個人經驗,有些人就是覺得某個業務他更加貼近domain,也有人認為這個業務是貼近service的。由於劃分標準的不確定性,帶來的後果就是實際項目中會產生很多這樣的爭議和糾紛,不同的人會有不同的劃分方法,最後就會造成整個項目的邏輯分層混亂。這不像貧血模型中我提出的按照是否依賴持久化進行劃分,這種標準是非常確定的,不會引起爭議,因此團隊開發中,不會產生此類問題。
5、貧血模型的domain object確實不夠rich,但是我們是做項目,不是做研究,好用就行了,管它是不是那麼純的OO呢?其實我不同意firebody認為的貧血模型在設計模型和實現代碼中有很大跨越的説法。一個設計模型到實現的時候,你直接得到兩個類:一個實體類,一個控制類就行了,沒有什麼跨越。
參考資料