背景
? ? ? 領(lǐng)域驅(qū)動設(shè)計(DDD)就是將業(yè)務領(lǐng)域概念對應到軟件構(gòu)件。關(guān)于這個主題的大多數(shù)作品和文章基于Eric Evans的書《領(lǐng)域驅(qū)動設(shè)計》——它主要從概念和設(shè)計的角度講解了領(lǐng)域建模和設(shè)計方向。這些作品討論了DDD的主要元素,例如實體,值對象,和服務等等,或者談論一些概念,像統(tǒng)一語言,邊界上下文和防腐層。
? ? ? 這篇文章的目的是從如何使用領(lǐng)域模型并且真正能實現(xiàn)它的角度談論領(lǐng)域建模與設(shè)計。我們將看一下指南,最佳實踐,以及技術(shù)領(lǐng)導和架構(gòu)師能夠在實現(xiàn)時使用到的框架和工具。領(lǐng)域驅(qū)動設(shè)計與開發(fā)也會被一些架構(gòu),設(shè)計和實現(xiàn)方面影響,例如:
? ? ? ?業(yè)務邏輯
? ? ? ?持久化
? ? ? ?緩存
? ? ? 事物管理
? ? ? 安全
? ? ? 代碼生成
? ? ? 測試驅(qū)動
? ? ? 重構(gòu)
? ? ? 這篇文章討論這些不同的因素如何在整個生命周期中影響項目實現(xiàn),以及架構(gòu)師應該尋找什么來用于完成一個成功的DDD實現(xiàn)。我將從一個典型的領(lǐng)域模型應該有的特征列表開始,以及什么時候在一個企業(yè)中使用領(lǐng)域模型(相對于一點也不使用領(lǐng)域模型或者使用一個貧血模型)。
? ? ? 文章包含一個簡單的貸款處理應用來描述這里討論的能夠在真實的領(lǐng)域驅(qū)動開發(fā)的項目中使用的設(shè)計方案和開發(fā)最佳實踐。這個簡單的應用在使用一些框架,像Spring,Dozer,Spring Security, JAXB,Arid POJOs和Spring Dynamic Modules實現(xiàn)貸款處理的領(lǐng)域魔偶性。實例代碼是JAVA,但是無論什么語言背景,大多數(shù)開發(fā)人員也是相當容易理解的。
介紹
? ? ? ?一個領(lǐng)域模型提供了多個好處。下面是其中的一些:
它幫助團隊在公司業(yè)務方和IT方建立了一個基本的模型,團隊可以使用它來討論業(yè)務需求,數(shù)據(jù)實體和處理模型。
模型是模塊化的,可擴展以及容易維護的,因為設(shè)計本身反應了業(yè)務模型。
它改善了業(yè)務領(lǐng)域?qū)ο蟮目芍赜眯院涂蓽y試性。
從相反的方面,我們看看當IT團隊在開發(fā)中到大型企業(yè)軟件應用時不使用領(lǐng)域模型的方法會發(fā)生什么。
? ? ? ?在領(lǐng)域模型和開發(fā)上不投入精力導致一個包含“滿滿的服務層”和“貧血模型層”的應用架構(gòu)——facade類(常常是一個無狀態(tài)的會話Bean)開始堆積越來越多的業(yè)務邏輯,并且領(lǐng)域?qū)ο笞兂蓛H僅有g(shù)etter和setter方法的數(shù)據(jù)載體。這種方式也導致領(lǐng)域特定業(yè)務邏輯和規(guī)則被分散(或者在多個場景中重復)在多個不同的facade類中。
? ? ? ?在大多數(shù)場景下,貧血領(lǐng)域模型不是很劃算。它們不能給公司帶來比其它公司有競爭力的優(yōu)勢,因為在這種架構(gòu)中實現(xiàn)領(lǐng)域業(yè)務規(guī)則的改變將花費很長時間開發(fā)和部署到產(chǎn)品環(huán)境。
在我們看一個DDD實現(xiàn)項目的架構(gòu)和設(shè)計考慮點前,讓我們看看一個富領(lǐng)域模型的特征。
? ? ? 領(lǐng)域模型應該關(guān)注一個特定的業(yè)務可操作領(lǐng)域。它應該和業(yè)務模型,策略和業(yè)務流程一致。
? ? ? 它應該和業(yè)務中的其它領(lǐng)域以及架構(gòu)中的其它層隔離。
? ? ? 它應該可重用從而避免相同核心業(yè)務領(lǐng)域元素的任何重復模型和實現(xiàn)。
? ? ? 一個模型應該與應用中的其它層松散耦合,意味著在領(lǐng)域?qū)拥娜魏我贿厸]有依賴。
? ? ? 它應該是一個抽象和獨立的層使更加易于維護,測試和版本。領(lǐng)域類應該是在容器之外可單元測試的。
? ? ? 它應該是使用POJO變成模型來設(shè)計的,沒有任何技術(shù)或者框架的依賴。
? ? ? 它應該是與持久化具體實現(xiàn)獨立。
? ? ? 它應該在任何基礎(chǔ)架構(gòu)上有最少的依賴,因為它將離開這些框架仍可以使用。我們不能在任何額外的框架上有任何強的依賴。
? ? ? 為了在軟件開發(fā)精力方面達到更好的投資收益,業(yè)務組和IT的高級管理部門必須允許在業(yè)務領(lǐng)域建模和實現(xiàn)上投入精力(時間,金錢和資源)。讓我們看看實現(xiàn)一個領(lǐng)域模型的其它必要因素:
? ? ? ?團隊應該可以正常訪問業(yè)務領(lǐng)域主題專家
? ? ? ?IT團隊(建模人員,架構(gòu)師和開發(fā)人員)應該掌握好的建模和設(shè)計技能。
? ? ? ?分析人員應該有好的業(yè)務過程建模技術(shù)。
? ? ? ?架構(gòu)師和開發(fā)人員應該有很強的面相對象誰及和開發(fā)經(jīng)驗。
企業(yè)架構(gòu)中領(lǐng)域驅(qū)動設(shè)計的角色
領(lǐng)域建模和DDD在企業(yè)架構(gòu)中有著至關(guān)重要的角色。因為企業(yè)架構(gòu)的一個目標就是使IT與業(yè)務組保持一致,領(lǐng)域模型——正是業(yè)務實體的體現(xiàn),就成為企業(yè)架構(gòu)的一個核心部分。這是為什么大多數(shù)企業(yè)架構(gòu)組件(業(yè)務或者基礎(chǔ))應該圍繞著領(lǐng)域模型來設(shè)計和實現(xiàn)。
領(lǐng)域驅(qū)動設(shè)計與SOA
? ? ? 面向服務架構(gòu)在過去的幾年里越來越強進,幫助團隊基于業(yè)務流程創(chuàng)建軟件組件和服務并且加快新產(chǎn)品推向市場的時間。領(lǐng)域驅(qū)動設(shè)計是SOA架構(gòu)的一個關(guān)鍵元素因為它幫助封裝業(yè)務流程和規(guī)則到一個領(lǐng)域?qū)ο笾?。領(lǐng)域模型也提供了語言和上線文,根據(jù)它服務契約能夠被定義。
? ? ? SOA的花費包含領(lǐng)域模型的設(shè)計和實現(xiàn)如果它還不存在的話。如果我們過度強調(diào)SOA的服務而忽略領(lǐng)域模型的重要性,我們最終將會得到一個充斥著貧血模型和泛濫的服務的應用架構(gòu)。
? ? ? 完美的場景是DDD的精力應伴隨著開發(fā)應用層和SOA組件的同時來實現(xiàn),因為這些是領(lǐng)域模型元素的直接消費者。隨著豐富的領(lǐng)域?qū)崿F(xiàn),SOA設(shè)計也變得相對簡單通過提供訪問領(lǐng)域?qū)ο蟮耐鈿ぃù恚5侨绻覀兓ㄙM太多精力在SOA層而不關(guān)注背后的合適的領(lǐng)域模型,業(yè)務服務將是一個不完整的領(lǐng)域模型,帶來一個脆弱的SOA架構(gòu)。