原文地址:http://blog.csdn.net/zhaome/article/details/5154193
領域模型是作為設計軟件對象的啟發來源,也是后續工件的必須輸入。
領域模型是說明問題域里(對建模者來說)有意義的領域類,它是面向對象分序的時候要創建的最重要的工作(必須說明,用例雖然也是一個重要的分析工作,但它並不是面向對象的,它是強調的概念的過程視圖)。
一、領域建模的思想及其方法學問題
什么是“問題域”和“領域建模”?
問題域:
現實世界中系統所要解決問題的領域為“問題域”,如“銀行業務”屬於“銀行的問題域”。
領域建模:
1.我們設計一個系統,總是希望它能解決一些問題,這些問題總是會映射到現實問題和概念。
2,對這些問題進行歸納、分析的過程就是領域建模(這個域,指的就是問題域)。
建立領域模型的好處:
1,通過建立領域模型能夠從現實的問題域中找到最有代表性的概念對象
2,並發現出其中的類和類之間的關系,因為所捕捉出的類是反饋問題域本質內容的信息。
經典的面向對象的分析或調研的步驟,是把一個相關的領域,分解為單個領域類或者對象(是一個我們能夠理解的概念)。
領域模型是領域類或者是我們感興趣的現實對象的可視化表示。
它們也被稱之為:概念模型、領域對象模型、分析對象模型等。
在UML中,領域模型是不定義操作(方法)的一組類圖來說明,它主要表達:
1, 領域對象或者領域類
2, 領域類之間的關聯
3, 領域類的屬性
屬性用以表達對象的狀態。
(1)三種領域類
1,邊界對象:參與者使用該對象與系統進行交流,也即邊界對象代表系統的內部工作和它所處環境之間的交互。
邊界對象將系統的其它部分和外部的相關事物隔離和保護起來。其主要的責任是:輸入、輸出和過濾。
2,實體對象:代表要保存到持續存儲體中的信息。實體類通常用業務域中的術語命名。
通過它可以表達和管理系統中的信息。在模型中,系統中的關鍵概念以實體對象來表現。其主要的責任是:業務行為的主要承載體
3,控制對象:它協調其他類的工作,每個用例通常有一個控制類,控制用例中的時間順序。
它可能是與其它對象協作以實現用例的行為,控制類也稱管理類。其主要的責任:控制事件流,負責為實體類分配責任
有四個規則對應上面的三種分析類對象間的交互
1,用例的參與者只能與邊界對象交互(這相當於結構化分析里面的自動化邊界)
2,邊界對象只能與控制對象和動作者交互(即不能直接訪問實體對象)
3,實體對象只能與控制對象交互
4,控制對象可以和邊界對象交互,也可以和實體交互,但是不能和動作者交互
三種領域類的UML的圖示如下:
(2)領域建模的簡單例子
下面舉個簡單的例子,說明領域建模的基本概念。
1)問題的描述
例如:兩個領域類Payment(支付)Sale(售出)在領域模型中以一種有意義的方式關聯。
2)關鍵概念
仔細考察上面的圖,可以看出,領域模型實際上是可視化了領域中的單詞或領域類,並且為這些單詞建立了領域類。
也就是說,領域模型是抽象了一個可視化字典。
模型展現了部分視圖或抽象,而忽略了建模者不感興趣的細節。
它充分利用了人類的特點—大腦善於可視化思維。
3)領域模型不是軟件組件的模型
領域模型視相關現實世界領域中事務的可視化表示,不是Java或者C#類這樣的軟件組件。
下面這些元素不適合在領域模型中表述:
1,軟件工件(窗口或數據庫)
2,職責或者方法:方法是個純粹的軟件概念,在設計工作期間考慮對象職責是非常重要的,但領域模型不考慮這些問題,在這里考慮職責的正確方法是,給對象分配角色(比如收銀員)。
4)領域類
領域模型表示領域中的領域類或詞匯,一個不是太准確的描述:一個領域類就是一個觀點、事務或者對象。
比較准確的表達:
領域類可以按照它的符號、內涵和外延來考慮。
l 符號:代表一個領域類的單詞或者圖片。
l 內涵:領域類的定義。
l 外延:領域類定義的一組實例。
二、領域類的識別
我們的目標是在相關領域中創建有意義的領域類。
比如說創建“處理銷售”用例中的相關領域類。
一般來說,用大量細粒度的領域類來充分描述領域模型,比粗略描述要好。
下面是識別領域類的一些指導原則:
l 不要認為領域模型中領域類越少越好,情況往往恰恰相反。
l 在初始識別階段往往會漏掉一些領域類,在后面考慮屬性和關聯的時候才會發現它,這是應該把它加上。
l 不要僅僅因為需求中沒有要求保留一些領域類的信息,或者因為領域類沒有屬性,就排除掉這個領域類。
l 無屬性的領域類,或者在問題域里面僅僅擔當行為的角色,而非信息的角色的領域類,都可以是有效的領域類。
1)識別領域類的策略
下面提供了兩種識別領域類的技巧。
1. 使用領域類分類列表。
2. 識別名詞短語。
2)使用領域類分類列表
通過建立一個候選的領域類的列表,來開始建立模型。下面是一個從商店和航空訂票領域中抽取出來的概念列表(注意,排列不考慮重要性)。
領域類分類
示例
物理或具體對象
(略)
事物的設計、描述、或規范
位置
交易
交易項目
人的角色
其它事物的容器
容器包含的元素
在該計算機之外的其它計算機或電子機械系統
抽象名詞的概念
組織
過程(通常不表示一個概念,但可以被表示成一個概念)
規則和政策
分類
有關工作、契約和法律事務的記錄
財務設施及服務
手冊、文檔、引用論文、書籍
3)根據名詞短語識別找出領域類
曾經有人提出了用名詞短語分析找出領域類的方法,然后把它們作為候選的領域類或者屬性。使用這種方法必須十分小心,從名詞機械的映射肯定是不行的,而且自然語言中的單詞本來就是模棱兩可的。
不過,這仍然是靈感的另一種來源,比如,我們來看一看原來寫出來的“處理銷售”的用例:
基本流程:
1.顧客攜帶購買的商品到達POS機收費口
2.收銀員開始一次新的銷售
3.收銀員輸入商品標識
4.…..
重復 3 – 4 步,直到結束。
5.………
…….
10.顧客攜帶商品和收據離開
仔細研究其中的名詞,可以看到很多有用的領域類(“記賬”、“提成”),也可能有些是屬性,請研究我們后面要討論的關於區分屬性的和類的討論。
這種方法的缺點就是不精確,但對我們研究問題會非常有用。
推薦:
把領域類分類,和詞語分析一起使用。
三、領域建模的指導原則
1)事物的命名和建模
領域模型是問題域中的概念或這是事物的地圖,所以地圖繪制員的策略,也適用於領域模型的建模。
l 使用地域中已有的地名(和城市名相同)
l 排除不相關的特性(比如居民人數)
l 不添加不屬於某個地方的事物(比如虛構的山川)
以此,我們建議使用如下的原則:
l 給領域模型建模,要使用問題域中的詞匯。
l 把和當前不相關的領域類排除在問題域之外。
l 領域模型應該排除不在當前考慮下的問題域中的事物。
2)在識別領域類的時候一個常犯的錯誤
在建立領域模型的時候,最常犯的一個錯誤就是把原本是類的事物當作屬性來處理。
Store(商店)是Sale(出售)的一個屬性呢?還是單獨的領域類Store?
大部分的屬性有一個特征,就是它的性質是數字或者文本。
而商店不是數字和文本,所以Store應該是個類。
另一個例子:
考慮一下飛機訂票的問題,Destination(目的地)應該是Flight(航班)的屬性呢還是一個單獨的類Airport(包括屬性name)。
在現實世界中,目的地機場並不是數字和文本,它是一個占地面積很大的事物,所以應該是個領域類。
建議:
如果我們舉棋不定,最好把這樣的事物當做一個單獨的領域類,因為領域模型中,屬性非常少見。
四、分析相似的領域類
有一些情況是比較不太容易處理的。
舉個例子,我們來分析一下“Register(記錄)”和“POST(終端)”這兩個概念。
POST作為一個銷售終端,可以是客戶端任何終點的設備(用戶PC,無線PDA),但早期商店是需要一個設備來記錄(Register)銷售。
而POST實際上也需要這個能力。
可見,Register是一個更具抽象性的概念,在領域模型中,是不是應該用Register而不是POST嗎?
我們應該知道,領域模型其實沒有絕對正確和錯誤之分,只有可用性大小的區分。
根據繪圖員原則,POST是一個領域中常見的術語,從熟悉和傳遞信息的角度,POST是一個有用的符號。
但是,從模型的抽象和軟件實現相互獨立的目標來看,Register是一個更具吸引力和可用性的表達,它可以方便的表達記錄銷售位置的概念,也可以表達不同的終端設備(如POST)。
兩種方式各具優點,關鍵是看你的領域類重點是表達什么信息。
這也是一個架構師必備的能力—抓住重點。
五、為非現實世界建模
一些業務領域有自己獨特的概念,只要這些概念是在業內被認可的,同樣可以創建領域類,比如在電信業可以建立這樣的領域類:
消息(Message)、連接(Connection)、端口(Port)、對話(Dialog)、路由(Route)、協議(Protocol)等。
六、規格說明或者描述領域類
在領域模型中,對領域類作規格說明的需求是相當普遍的,因此它值得我們來強調。
假定有下面的情形:
l 一個Item實例代表商店中一個實際存在的商品
l 一個Item表達一個實際存在的商品,它有價格,ID兩個描述信息
l 每次賣掉一個商品,就從軟件中刪掉一個實例。
如果我們是這樣來表達:
那很可能會認為隨着商品的賣出,它的價格也刪掉了,顯然這是不對的。
比較好的表達方式是這樣的:
1)何時需要規格說明類
在下面的情況下,需要添加領域類的說明類:
l 商品或服務的信息描述,獨立於商品或者服務當前已經存在的任何實例。
l 刪除所描述的事物,會導致維護信息的丟失。
l 希望減少冗余或者重復的信息。
2)服務的描述
作為領域類的實例可以是一次服務而不是一件商品,比如航空公司的航班服務。
假定航空公司由於事故取消了6個月的航班,這時它對應的Flight(航班)軟件對象也在計算機中刪除了,那么,航空公司就不再有航班記錄了。
所以比較好的辦法是添加一個FlightDestination(航班目的)的規格描述類,請看下面的例子。
七、統一過程中的領域模型
根據“統一過程的時間及其時間安排”的那張表,在UP中,通常在細化階段開始並完成領域模型的建模。事實上,對於一個有經驗的系統構架師,在每次迭代里開發領域模型,只需要幾個小時就夠了。
在UP中,有一個業務對象模型(BOM),但實際上並不通用,而領域模型實際上是BOM的一個正是的變體。在RUP中,BOM是這樣來定義的:它是業務員和業務實體如何相關聯,以及為了完成業務如何寫作的抽象。
BOM可以用多種不同的圖(類圖、活動圖、順序圖)來表示,這些圖說明整個企業應該如何運行。
不過對於單個軟件的應用,這似乎是個不太通用的活動。盡管它還有一些變通,但是在系統架構設計中,領域模型仍然是最為廣泛的被采用的。
第二節 領域模型的關聯
一、找出關聯
關聯,是類(事實上是實例)指示有意義或相關連接的一種關系。
關聯事實上表示是一種“知道”。
如果不寫箭頭,關聯的方向一般是“從上到下,從左到右”。
我們可以使用下面的表來找出關聯
分類
示例
A在物理上是B的一部分
(略)
A在邏輯上是B的一部分
A在物理上包含在B中/依賴於B
A在邏輯上包含在B中
A是對B的描述
A是交易或者報表B中的一項
A為B所知道/為B所記錄/為B所撲獲
A是B的一個成員
A是B的一個組織子單元
A使用或者管理B
A與B通信
A與一個交易B有關
A是一個與另一個B有關的事物
A與B相鄰
A為B所擁有
A是一個與B有關的事件
二、關聯的指導原則
l 把注意力集中在那些需要把概念之間的關系信息保持一段時間的關聯(“需要知道”型關聯)。
l 太多的關聯不但不能有效的表示領域模型,分而會使領域模型變的混亂,有的時候發現某些關聯很費時間,但帶來的好處並不大。
l 避免顯示冗余或者導出的關聯。
三、角色和多重性
關聯的每一端稱之為“角色”。
角色可選的具有:
名稱;
多重性表達式;
導航性。
多重性
多重性表示一個實例,在一個特定的時刻,而不是一段時間內,可以和多個實例發生關聯。
“*”表示多個。
“1”表示一個。
“0..1”表示1或者沒有,比如一個商品在貨架上,可能售出,也可能被丟掉了,這種情況,用“0..1”是合理的。問題是我們需要關心這樣的觀點嗎?如果是數據庫,可能表達這個數據存在,或者損壞。但在領域模型並不表示軟件對象,通常我們只對我們有興趣的內容建模,從這個觀點出發,也可能只有“1”或者“*”是合理的。
再一次提醒,發現領域類比發現關聯更重要,花費在領域模型創建的大部分時間,應該被用於發現領域類,而不是關聯。
四、兩種類型之間的多重關聯
兩種類型之間的多重關聯是可能存在的。
比如航空公司的例子,Flight-to和Flight-from可能會同時存在,應該把它們都標出來。
第三節 領域模型的屬性
發現和識別領域類的屬性,是很有意義的。
屬性是個邏輯對象的值。
屬性主要用於保留對象的狀態。
一、有效的屬性類型
大部分屬性應該是簡單數據類型。
當然也可以使其它的一些必要的類型,比如:Color(顏色)、Address(地址)、PhoneNumber(電話號碼)等。
二、非原始的數據類型類
在領域類中,可以把原始數據類型改成非原始數據類型,請應用下面的指導原則:
l 由分開的段組成數據(電話號碼,人名)
l 有些操作和它的數據有關,如分析和驗證等(社會安全號碼)
l 包含其它屬性的數據(促銷價格的開始和結束時間)
l 帶有單位的數據值(支付金額有一個貨幣單位)
l 對帶有上述性質的一個或多個抽象(商品條目標識符)
如果屬性是一個數據類型,應該顯示在屬性框里面。