領域模型的概念及作用
領域模型是對領域內的概念類或現實世界中物件的視覺化表示。又稱概念模型、領域物件模型、分析物件模型。它專注於分析問題領域本身,發掘重要的業務領域概念,並建立業務領域概念之間的關係。概念比較深奧,其實說白了就是我們把基於對業務的理解畫成一個類圖,並畫出這些類之間的關係(物件導向)。
領域模型可以整理業務中的概念以及關係,幫助團隊中的成員對業務的理解保持一致,往後可以指導資料庫設計、系統功能設計、指導開發。在整個系統建設週期能起到 上接需求,下承開發 的作用。
那既然領域模型如此重要,我們是不是要在類圖中儘可能的展示物件的屬性和方法,以便更好的指導後續的開發設計。
恰恰相反,我們在建模的時候不要將注意力集中在屬性或行為上,應該擺脫這些細枝末節,抓住領域物件定義的最基本特徵,只需要體現物件模型的重要概念。如果細節過多很容易產生 ”只見樹木,不見森林“ 的現象。
下面我們看一個簡化後的報銷業務的領域模型,加深一下印象。
完成一個領域模型建模,主要需要做兩件事:
- 定義類的關鍵屬性和關鍵行為;
- 定義類與類之間的關聯關係。
定義類的屬性和行為
定義類的屬性和行為比較簡單,用設計工具拖一個class即可,這裡只需要注意一下屬性和行為的訪問許可權。
- 表示private
# 表示protected
~ 表示default,也就是包許可權
+ 表示public
定義類與類之間的互動關係
在UML類圖中,定義了六種類之間的關係,他們分別是: 泛化(Generalization), 實現(Realization),關聯(Association),聚合(Aggregation),組合(Composition),依賴(Dependency)。關係比較多,而且有些還比較相近,比如聚合和組合,接下來我們逐漸講解:
泛化(Generalization)
介紹:
泛化(Generalization)表示類與類之間的繼承關係,介面與介面之間的繼承關係。
圖例:
使用 空心三角形+實線 表示。
程式碼實現:
public class A {
}
public class B extends A {
}
實現(Realization)
介紹:
實現(Realization)表示一個class類實現interface介面(可以是多個)的功能。
圖例:
使用 空心三角形+虛線 表示。
程式碼實現:
public interface A {
}
public class B implements A {
}
聚合(Aggregation)
介紹:
聚合(Aggregation)表示一種弱的 ‘擁有’ 關係,即has-a的關係,體現的是A物件可以包含B物件,B類生命週期可以不依賴A類物件的生命週期, 也就是說可以單獨銷燬A類物件而不影響B類物件,比如課程與學生之間的關係。
圖例:
使用 空心的菱形+實線箭頭 表示。
程式碼實現:
public class A {
private B b;
public A(B b){
this.b = b;
}
}
組合(Composition)
介紹:
組合(Composition)表示一種強的 ‘擁有’ 關係,即contains-a的關係,體現的是A物件包含B物件,B類生命週期依賴A類物件的生命週期,B類物件不可單獨存在,比如鳥與翅膀之間的關係。
圖例:
使用 實心的菱形+實線箭頭 表示,還可以使用連線兩端的數字表示某一端有幾個例項。
程式碼實現:
public class A {
private B b;
public A () {
this.b = new B();
}
}
關聯(Association)
介紹:
關聯(Association)是一種非常弱的關係,包含聚合、組合兩種關係。對於兩個相對獨立的物件,當一個物件負責構造另一個物件的例項,或者依賴另一個物件的服務時,這兩個物件之間主要體現為依賴關係。具體到程式碼層面,如果B類是A類的成員變數,那麼B類和A類就是關聯關係。
圖例:
使用實線箭頭表示。
程式碼實現:
public class A {
private B b;
public A(B b){
this.b = b;
}
}
或者
public class A {
private B b;
public A () {
this.b = new B();
}
}
依賴(Dependency)
介紹:
依賴(Dependency) 是比關聯關係更加弱的關係,包含關聯關係。不管是B類物件是A類物件的成員變數,還是A類方法使用B類物件作為引數或者返回值、區域性變數,只要B類物件和A類物件有任何使用關係,我們都稱他們有依賴關係。
圖例:
使用 虛線箭頭 表示。
程式碼實現:
public class A {
private B b;
public A(B b){
this.b = b;
}
}
或者
public class A {
private B b;
public A () {
this.b = new B();
}
}
或者
public class A {
public void func(B b)
...
}
}
模型簡化
嚴格的UML類圖之間的關係拆分的太細,專業要求很高,大大增加了學習成本,而且對於業務溝通,指導後續資料庫設計,程式設計開發沒有太大意義。
所以在實際業務建模過程中,我們並不需要嚴格按照UML類圖互動關係來描述業務實體之間的關係,比如我們可以將聚合、組合、關聯統統使用關聯關係表示,使用實線連線兩個實體,並在兩側標記出例項個數即可。
小結
領域模型最終呈現後的結果很簡單,但是過程卻很複雜。需要架構師基於自身的業務知識和類似產品的參考,再結合客戶、業務專家、領域專家的諮詢和指導,需要經過不斷推倒、修改優化才能完成。
對於剛開始接觸領域模型的繪製時經常會出現下面兩種典型錯誤:
- 將待開發系統也放在領域模型裡面
待開發系統要不要出現在領域模型中取決於你的業務離開待開發的系統能不能玩的轉。舉個例子:如果開發的是共享單車的資訊系統,共享單車離開資訊系統肯定玩不轉,所以這時候資訊系統需要出現在領域模型。 - 概念劃分不清,關係沒有畫到位
比如屬性畫成了類,繼承關係搞錯