三、建立技術(shù)框架
這一點(diǎn),是《領(lǐng)域驅(qū)動設(shè)計(jì)》這本書沒有過多提及的內(nèi)容。這個需要結(jié)合你們公司的原來技術(shù)框架用最小化改造成本最大化收益的方式來建立領(lǐng)域驅(qū)動的技術(shù)框架。下面是一個可以廣泛使用的領(lǐng)域驅(qū)動的技術(shù)框架,可以在這之上增加更多的個性元素形成你公司自己的框架。

圖3 領(lǐng)域驅(qū)動設(shè)計(jì)參考技術(shù)框架圖
這個框架的各個元素基本上在 《領(lǐng)域驅(qū)動設(shè)計(jì)》一書中都可以找到對應(yīng)的解釋,但這里需要解釋一下我建立這個框架的個性理解:
領(lǐng)域?qū)ν?頁面、AJAX、ESB調(diào)用)只暴露領(lǐng)域服務(wù),其它所有領(lǐng)域類都是包內(nèi)自閉的,對外不可見。
基礎(chǔ)倉庫的引入,基礎(chǔ)倉庫是一個抽象的倉庫,它封裝了大量常用工具方法、業(yè)務(wù)對象生命周期維護(hù)(實(shí)體OR映射、DAO調(diào)用)、外部接口調(diào)用?梢越档蜆I(yè)務(wù)倉庫不必要的重復(fù)編碼與復(fù)雜性。業(yè)務(wù)倉庫是繼承基礎(chǔ)倉庫的子類。
基礎(chǔ)設(shè)施的引用,基礎(chǔ)設(shè)施是用來承載引用非領(lǐng)域調(diào)用的樁,我們在使用領(lǐng)域驅(qū)動設(shè)計(jì)的時候往往是從一個舊的系統(tǒng)重構(gòu)開始。這時我們不可能要求所有的業(yè)務(wù)子系統(tǒng)相互調(diào)用都通過Domain Service調(diào)用,這時我們可以通過Infrastructure優(yōu)美的把調(diào)用封裝在業(yè)務(wù)倉庫的業(yè)務(wù)方法內(nèi)。
四、重構(gòu)受影響領(lǐng)域的設(shè)計(jì)與編碼
圖4 重構(gòu)后的商品詳情頁類圖
Spark以商品詳情頁這個Use Case為例展示了以領(lǐng)域驅(qū)動設(shè)計(jì)的重構(gòu)類圖:
增加行為表ProductExt用于存儲商品的擴(kuò)展信息,如預(yù)約時間段、預(yù)約醫(yī)院。并為表建立一一對應(yīng)的實(shí)體Entity。
基礎(chǔ)倉庫Repository通過Infrastructure中的DAO封裝了對實(shí)體的操作,如create()、update()、delete()、findById()、findList()
商品業(yè)務(wù)倉庫ProductRepository擴(kuò)展了基礎(chǔ)倉庫,客戶程序可以用productId為參數(shù),通過ProductVo.getProduct()方法獲得商品詳細(xì)信息的業(yè)務(wù)實(shí)現(xiàn),由于業(yè)務(wù)倉庫的的公開方法對外返回的都是Value Object,因此不會直接暴露Entity類型給客戶程序。
GetProductService服務(wù)類通過invoke()服務(wù)方法 對外(商品詳情頁面)提供服務(wù),它通調(diào)用業(yè)務(wù)倉庫中的業(yè)務(wù)方法,并將接口規(guī)格化。
在Spark的幫助下,Jack Chen成功的脫離了困境。現(xiàn)在他正在公司里積極推行自己的領(lǐng)域驅(qū)動設(shè)計(jì)框架,他們公司的網(wǎng)站正在以每三周一次的重構(gòu)速度快速迭代演進(jìn)。他象Spark一樣,成為了一個領(lǐng)域驅(qū)動的布道者。
來源:InfoQ