領(lǐng)域驅(qū)動設(shè)計與開發(fā)實踐(2)【翻譯】

簡單的應(yīng)用

? ? ? 本文使用的是一個簡單的家庭借貸處理系統(tǒng),業(yè)務(wù)用例是審批一個家庭借貸(抵押借貸)的資金請求。當(dāng)提交一個資金申請到抵押借貸公司,請求首先經(jīng)過保險流程,核保人員根據(jù)用戶的收入詳情,信用記錄和其它因素批準(zhǔn)或者拒絕貸款請求。如果資金申請審批通過,它將通過借貸審批流程的關(guān)閉和出資過程。

? ? ? 借貸處理系統(tǒng)的出資模塊自動把出資支付款的流程發(fā)給借款人。一個典型的出資流程是從抵押放貸者(銀行)開始,轉(zhuǎn)發(fā)借貸文件到一個債券公司。債券公司然后重新審查借貸文件并且與賣方和買方約定時間關(guān)閉這個借貸。借款方和賣方在產(chǎn)權(quán)公司同意關(guān)閉貸款并簽署文件移交資產(chǎn)。

架構(gòu)

? ? ? 典型的企業(yè)應(yīng)用架構(gòu)包含下面4個概念層:

·用戶層(展示層):負(fù)責(zé)展示信息和解釋用戶的命令

·應(yīng)用層:這層協(xié)調(diào)應(yīng)用的活動。它不包含任何業(yè)務(wù)邏輯。它不持有任何業(yè)務(wù)對象的狀態(tài),但是持有任何應(yīng)用任務(wù)流程的狀態(tài)。

·領(lǐng)域?qū)樱哼@層包含業(yè)務(wù)領(lǐng)域的信息,業(yè)務(wù)對象的狀態(tài)在這里。業(yè)務(wù)對象的持久化和它們的狀態(tài)委托給基礎(chǔ)框架。

·基礎(chǔ)架構(gòu)層:這層為其它層提供支持。它提供了層之間的通信,實現(xiàn)了業(yè)務(wù)對象的持久化,包含用戶層的支持庫等等。

讓我們更詳細(xì)地了解一下應(yīng)用層和領(lǐng)域?qū)?。?yīng)用層:

·負(fù)責(zé)在應(yīng)用程序內(nèi)用戶界面見的導(dǎo)航,與其它系統(tǒng)的應(yīng)用層交互

·在將用戶輸入數(shù)據(jù)傳輸給應(yīng)用的低層時,進(jìn)行基本的驗證(與業(yè)務(wù)邏輯無關(guān)的驗證)

·不包含任何與業(yè)務(wù)或領(lǐng)域相關(guān)的邏輯或數(shù)據(jù)訪問邏輯

·沒有任何反應(yīng)業(yè)務(wù)用例的狀態(tài),但是管理用戶會話的狀態(tài)或者任務(wù)的處理狀態(tài)。

領(lǐng)域?qū)樱?/p>

·負(fù)責(zé)業(yè)務(wù)領(lǐng)域的概念,關(guān)于業(yè)務(wù)用例和業(yè)務(wù)規(guī)則。領(lǐng)域?qū)ο蠓庋b了業(yè)務(wù)對象的狀態(tài)和行為。一個貸款處理系統(tǒng)的業(yè)務(wù)實體的例子有抵押,資產(chǎn)和借款人。

·如果一個用例跨多個用戶請求 (例如:貸款注冊過程包含多個步驟:用戶輸入貸款詳情,系統(tǒng)基于貸款參數(shù)返回產(chǎn)品和利率,用戶選擇一個特定的產(chǎn)品/利率組合,最終系統(tǒng)在這個利率上鎖定這次貸款),它也管理這個業(yè)務(wù)用戶的狀態(tài)(會話)。

·包含服務(wù)對象——它們僅僅有一個定義的好的操作行為,這個行為不屬于任何領(lǐng)域?qū)ο?。服?wù)封裝了不適合領(lǐng)域?qū)ο笞陨淼臉I(yè)務(wù)領(lǐng)域的行為。

·是業(yè)務(wù)應(yīng)用的核心,并且應(yīng)該與應(yīng)用的其它層很好的隔離。同時,它也不應(yīng)該依賴于在其它層使用的框架。

圖2展示了應(yīng)用中使用的框架層以及它們怎么與DDD相關(guān)聯(lián)。


下面的設(shè)計方面被認(rèn)為是當(dāng)前DDD實現(xiàn)方法的主要元素:

·面向?qū)ο缶幊蹋∣OP)

·依賴注入(DI)

·面向切面編程(AOP)

(此處省略O(shè)OP,DI,AOP的翻譯段落)

業(yè)務(wù)規(guī)則

? ? ? 業(yè)務(wù)規(guī)則是業(yè)務(wù)領(lǐng)域的重要部分。它們定義了數(shù)據(jù)的有效性和其它需要在特定業(yè)務(wù)處理流程中附加到領(lǐng)域?qū)ο蟮募s束。業(yè)務(wù)規(guī)則典型的分為以下類型:

·數(shù)據(jù)校驗

·數(shù)據(jù)轉(zhuǎn)換

·業(yè)務(wù)決策

·流程路由(工作流邏輯)

? ? ? 在真實的DDD世界,上下文是非常重要的。上下文特征指明了領(lǐng)域?qū)ο蠛推渌\(yùn)行時因素的協(xié)調(diào)例如什么業(yè)務(wù)規(guī)則需要使用等等。校驗和其它業(yè)務(wù)規(guī)則一直在一個特定上下文中被處理。這意味著同一個領(lǐng)域?qū)ο?,在不同的上下文中,將會處理不同的業(yè)務(wù)規(guī)則。舉個例子,一個貸款領(lǐng)域?qū)ο蟮囊恍傩裕ㄈ缳J款金額和利率)在已經(jīng)通過審批流程的核保步驟后不能被修改。但是相同的屬性在貸款剛剛注冊并且在一個指定利率鎖定下可以被修改。

? ? ? 雖然所有領(lǐng)域特定業(yè)務(wù)規(guī)則都應(yīng)該被封裝在領(lǐng)域?qū)?,但是有些?yīng)用設(shè)計方法把規(guī)則放到外觀類(fa?ade classes)中,對于業(yè)務(wù)規(guī)格來說這導(dǎo)致領(lǐng)域類變成了“貧血性”。在小規(guī)模應(yīng)用程序中,這可以被接受的,在中大型包含復(fù)雜業(yè)務(wù)規(guī)則的應(yīng)用這種方法不推薦使用。更好的設(shè)計選擇是把規(guī)則放到屬于應(yīng)該屬于的領(lǐng)域?qū)ο笾?。如果一個業(yè)務(wù)規(guī)則邏輯跨2個或多個實體對象,那么它應(yīng)該屬于一個服務(wù)類的一部分。

? ? ? 同時,如果我們對應(yīng)用不是很勤奮,設(shè)計業(yè)務(wù)規(guī)則將最終已很多開關(guān)語句的形式被編碼。隨著時間業(yè)務(wù)規(guī)則變得更加復(fù)雜,開發(fā)人員沒有花時間重構(gòu)代碼把開關(guān)語句改為更加可管理的設(shè)計。代碼中硬編碼的復(fù)雜路由邏輯或者決策規(guī)則導(dǎo)致更長的方法體,重復(fù)代碼,和一個僵硬的應(yīng)用設(shè)計,終究成為一個維護(hù)的噩夢。一個好的設(shè)計是把所有規(guī)則(尤其是復(fù)雜規(guī)則——隨著業(yè)務(wù)策略變動而經(jīng)常改變的規(guī)則)放到一個規(guī)則引擎中(使用一個規(guī)則框架像JBoss Rules,OpenRules,或者M(jìn)andarax)并且在領(lǐng)域?qū)ο笾杏|發(fā)它。

? ? ? 驗證規(guī)則常常使用不同的語言實現(xiàn)像javascript,XML,Java code,和其它腳本語言。但是由于業(yè)務(wù)規(guī)則的動態(tài)天性,如Ruby,Groovy,或者Domain Specific Language(DSL)是更好的選擇去定義和管理規(guī)則。Structs(應(yīng)用層),Spring(服務(wù))和Hibernate(ORM)都有它們自己的驗證模塊,我們可以在這里對進(jìn)來和出去的數(shù)據(jù)對象使用驗證。在一些場景下,驗證規(guī)則也能被切面(Aspect)管理,它們能夠編入硬功的不能層(例如服務(wù)層和控制器)。

? ? ? 重要的是在寫領(lǐng)域類管理業(yè)務(wù)邏輯時牢記單元測試。任何規(guī)則邏輯的改變應(yīng)該很容易在隔離下進(jìn)行單元可測試。

? ? ? 這個簡單應(yīng)用包含了一些業(yè)務(wù)規(guī)則,驗證貸款參數(shù)在允許的產(chǎn)品和利率規(guī)格。規(guī)則使用腳本語言(Groovy)定義并且應(yīng)用在傳給FundingService對象的貸款數(shù)據(jù)上。


原文鏈接:Domain Driven Design and Development In Practice

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容