領(lǐng)域模型驅(qū)動(dòng)設(shè)計(jì)(Evans DDD)之模型提煉
板橋里人 http://www.jdon.com
2006/8/21
當(dāng)Java世界提供的可選擇性框架平臺(tái)越來(lái)越多時(shí),我們可能被平臺(tái)架構(gòu)所深深困擾,而無(wú)暇顧及軟件的真正核心:業(yè)務(wù)建模,其實(shí),業(yè)務(wù)領(lǐng)域建模同樣是一個(gè)比平臺(tái)架構(gòu)更復(fù)雜,更需要學(xué)習(xí)的新的領(lǐng)域。
相反,在實(shí)踐中,我們技術(shù)人員在經(jīng)過(guò)冗長(zhǎng)的平臺(tái)架構(gòu)學(xué)習(xí)和實(shí)踐后,就匆忙開始項(xiàng)目開發(fā),這時(shí)是什么指導(dǎo)他們進(jìn)行軟件業(yè)務(wù)實(shí)現(xiàn)呢?大部分可能是依賴數(shù)據(jù)庫(kù)
建模,甚至是復(fù)雜冗長(zhǎng)的數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程設(shè)計(jì),這些已經(jīng)開始走向面向?qū)ο蠓治鲈O(shè)計(jì)的反方向,走上了一條錯(cuò)誤的軟件開發(fā)方向,最終開發(fā)出緩慢的、經(jīng)常當(dāng)機(jī)的
Java企業(yè)系統(tǒng)。
如果你沒(méi)有恰當(dāng)?shù)腛O設(shè)計(jì)思想,Java就會(huì)用性能懲罰你,這可能是Java世界的一個(gè)潛規(guī)則。
那么,一個(gè)正確的OOA/OOD/OOP步驟是什么呢?目前圍繞模型驅(qū)動(dòng)設(shè)計(jì)(MDD)的設(shè)計(jì)思想成為主流思想,MDA更是在MDD基礎(chǔ)上提升和升華。下面讓我們首先了解,如何使用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)思想來(lái)分析設(shè)計(jì)一個(gè)軟件系統(tǒng)。
當(dāng)我們不再對(duì)一個(gè)新系統(tǒng)進(jìn)行數(shù)據(jù)庫(kù)提煉時(shí),取而代之的時(shí)面向?qū)ο蟮哪P吞釤挕N覀儽仨毚蟮堕煾貙?duì)業(yè)務(wù)領(lǐng)域進(jìn)行細(xì)分,將一個(gè)復(fù)雜的業(yè)務(wù)領(lǐng)域劃分為多個(gè)小的子領(lǐng)域,同時(shí)還必須分清重點(diǎn)和次要部分,抓住核心領(lǐng)域概念,實(shí)現(xiàn)重點(diǎn)突破。
核心領(lǐng)域模型
精簡(jiǎn)模型,找出核心領(lǐng)域,將業(yè)務(wù)需求中最有價(jià)值的概念體現(xiàn)出來(lái),讓核心變精要,這實(shí)際就是一個(gè)使復(fù)雜問(wèn)題變簡(jiǎn)單的過(guò)程,也是對(duì)我們軟件設(shè)計(jì)人員真正能力的考驗(yàn)。
核心領(lǐng)域模型不是輕易能夠發(fā)現(xiàn),特別是他處于一個(gè)紛亂復(fù)雜的眾多領(lǐng)域模型結(jié)構(gòu)中時(shí),核心模型通常是我們某個(gè)子領(lǐng)域關(guān)注的重點(diǎn),例如訂單模型是訂單管理領(lǐng)域的核心;消息模型是論壇或消息領(lǐng)域系統(tǒng)的核心。
目前,分析領(lǐng)域有很多模式來(lái)幫助我們來(lái)提煉核心模型,例如四色原型、Martin Fowler
的分析模式等,例如MF的"分析模式"(Analysis
Patterns)中的記帳模型就是不僅僅用來(lái)記錄賬目數(shù)值,而且可以記錄和控制賬目的每一次修改。而四色原型則是一種高于分析模式的一種原型基本模式,
下面是本人根據(jù)四色原型提煉的核心領(lǐng)域模型概念。
一般情況下,在企業(yè)應(yīng)用中,核心模型總是在其周圍圍繞一些所謂的“衛(wèi)星”,這實(shí)際上也是來(lái)自四色原型的一個(gè)推論,核心模型和其“衛(wèi)星”的類圖如下:

根據(jù)Eric
Evans在其“領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)”一書中定義,領(lǐng)域模型劃分為實(shí)體和值對(duì)象兩種,實(shí)體模型是指業(yè)務(wù)領(lǐng)域中具有獨(dú)立屬性的對(duì)象;而值對(duì)象則可能是一種
Description或狀態(tài)或規(guī)則。只要有實(shí)體對(duì)象,就可能存在實(shí)體的狀態(tài),狀態(tài)跟蹤有時(shí)成為一個(gè)業(yè)務(wù)領(lǐng)域使用計(jì)算機(jī)軟件的首要跟蹤,但是,數(shù)據(jù)庫(kù)不是
對(duì)象狀態(tài)的唯一表達(dá)方式,只是一種存儲(chǔ)方式(見 狀態(tài)對(duì)象:數(shù)據(jù)庫(kù)的替代者 )。
圖中,實(shí)體核心對(duì)象大部分可能有一種類型,例如核心模型是產(chǎn)品,那么存在產(chǎn)品目錄;核心模型是消息;就存在消息類型;核心模型是信息;總存在信息類別,我們總是使用分類方式來(lái)管理業(yè)務(wù)領(lǐng)域的信息,有時(shí),類別甚至復(fù)雜到樹形結(jié)構(gòu)。
核心實(shí)體模型有時(shí)會(huì)有一個(gè)1:N關(guān)聯(lián)的子實(shí)體,一般可能表達(dá)實(shí)體的細(xì)節(jié),例如:核心模型是訂單,那么存在訂單條目這樣一個(gè)細(xì)節(jié),一個(gè)訂單中可能有多個(gè)訂單條目;如果核心模型是信息,那么存在該信息的多個(gè)回復(fù)或評(píng)論;這樣的關(guān)聯(lián)一般存在多個(gè)業(yè)務(wù)領(lǐng)域中。
模型界面實(shí)現(xiàn)
原來(lái),我們以為分析設(shè)計(jì)階段無(wú)需了解實(shí)現(xiàn)細(xì)節(jié),分析人員只要悶頭做分析UML圖,而無(wú)需顧及如何具體實(shí)現(xiàn),其實(shí)這是一個(gè)誤區(qū)。
Eric Evans在其“領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)”一書中認(rèn)為:分析人員負(fù)責(zé)從領(lǐng)域中收集基本概念;
設(shè)計(jì)則必須指明一組適應(yīng)編程工具構(gòu)造的組件,以及這些組件必須能夠在目標(biāo)環(huán)境中有效執(zhí)行。模型驅(qū)動(dòng)設(shè)計(jì)(Model-Driven
Design)拋棄了分裂分析模型與設(shè)計(jì)的做法,使用單一的模型來(lái)滿足這兩方面的要求。因此,對(duì)于核心模型必須掌握了解其實(shí)現(xiàn)細(xì)節(jié)。
從另外一個(gè)方面來(lái)說(shuō),中國(guó)的客戶總是從界面設(shè)計(jì)來(lái)表達(dá)他們的意圖(如果中國(guó)客戶能夠使用Use
Case等UML圖來(lái)表達(dá)他們概念真是不可想象),例如客戶會(huì)說(shuō),我希望有一個(gè)界面讓我將訂單數(shù)據(jù)輸入,然后能夠查詢符合查詢條件的訂單。因此,我們的核
心模型至少能夠順利地映射到界面實(shí)現(xiàn),相反,這個(gè)客戶有這樣訂單界面要求,但是你沒(méi)有提供一個(gè)與之適應(yīng)的核心實(shí)體模型,界面實(shí)現(xiàn)將變得復(fù)雜,甚至走很多彎
路,誕生不少DTO垃圾對(duì)象。
以JdonFramework框架實(shí)現(xiàn)為例子,框架提供了圍繞
核心模型的新增刪除修改查詢(CRUD)功能以及批量功能的快速實(shí)現(xiàn),尤其CRUD功能實(shí)現(xiàn)前提是必須提煉出核心模型,從而其界面設(shè)計(jì)流程就能通過(guò)配置立
即實(shí)現(xiàn),這樣一步到位實(shí)現(xiàn)領(lǐng)域模型到界面的過(guò)渡,可以將我們?cè)O(shè)計(jì)核心模型和客戶要求的界面需求能夠做到完整的統(tǒng)一。
開源JdonFramework下載包中message案
例實(shí)際就是上述核心模型圖的一種實(shí)現(xiàn)項(xiàng)目,更復(fù)雜的項(xiàng)目可以認(rèn)為是核心模型的重疊和反復(fù)使用(從原理上講,核心模型是四色原型的體現(xiàn),而四色原型被認(rèn)為是
大部分企業(yè)系統(tǒng)的基本組成元素,見[book][UML][Peter Coad]Java Modeling in Color with UML)。
核心模型的選擇
實(shí)際項(xiàng)目中,會(huì)存在多個(gè)核心模型的重疊和覆蓋使用,主要取決于你的領(lǐng)域關(guān)注重點(diǎn)。
例如當(dāng)客戶和我們說(shuō)要做一個(gè)旅游網(wǎng)站時(shí),我們必須充分了解需求,它的軟件系統(tǒng)重點(diǎn)是哪些功能。如果當(dāng)他首先說(shuō):我需要一個(gè)酒店設(shè)備的查詢系統(tǒng),因?yàn)樗?
客戶對(duì)酒店設(shè)備非常關(guān)注,那么我們可能認(rèn)為酒店設(shè)備是這個(gè)領(lǐng)域模型的核心;酒店設(shè)備。如果他又進(jìn)行描述:我需要一個(gè)界面,客戶在輸入酒店資料時(shí),選擇多個(gè)
酒店設(shè)備,那么在這樣一個(gè)關(guān)注領(lǐng)域,核心模型實(shí)際是酒店,而酒店設(shè)備可能成為酒店的一個(gè)特征實(shí)體屬性,甚至是值對(duì)象了。
以進(jìn)銷存系統(tǒng)為例子,在采購(gòu)系統(tǒng)中,采購(gòu)單是一個(gè)核心實(shí)體模型,而原材料是一種輔助實(shí)體模型;在庫(kù)存系統(tǒng)中,入出庫(kù)單是一個(gè)核心實(shí)體模型,原材料或成
品代表的是一個(gè)庫(kù)存物品概念模型,當(dāng)需要庫(kù)存報(bào)表查詢輸出,可以立即計(jì)算出來(lái),或?qū)⒔Y(jié)果緩存起來(lái),緩存起來(lái)的結(jié)果其實(shí)是庫(kù)存物品對(duì)象的狀態(tài),可以使用值對(duì)
象來(lái)實(shí)現(xiàn)。
核心模型的精練
當(dāng)核心模型被定位和確定后,相當(dāng)于我們抓住領(lǐng)域本質(zhì),這時(shí)我們可以使用面向?qū)ο蟮母拍顚?duì)模型進(jìn)行精練細(xì)化,實(shí)際就是明確對(duì)象的屬性,確定模型對(duì)象的邊
界,通過(guò)反復(fù)重構(gòu),結(jié)合GoF等設(shè)計(jì)模式,使得我們得模型準(zhǔn)確反映本質(zhì),從而實(shí)現(xiàn)模型的靈活性設(shè)計(jì)。所有這些,都是數(shù)據(jù)表驅(qū)動(dòng)設(shè)計(jì)所不能實(shí)現(xiàn)的。那你還抱
著數(shù)據(jù)庫(kù)建模干什么呢?
見下章: 模型驅(qū)動(dòng)設(shè)計(jì)(MDD)之靈活設(shè)計(jì)(續(xù))