What's DDD?
DDD的目標(biāo):創(chuàng)建可測(cè)試、可伸縮、組織良好的軟件模型。
DDD不是關(guān)于技術(shù)的,而是關(guān)于討論、聆聽(tīng)、理解和發(fā)現(xiàn)業(yè)務(wù)價(jià)值的,都是為了將知識(shí)集中起來(lái)。
但是并不是說(shuō)技術(shù)不重要,尤其是涉及到架構(gòu)與模塊設(shè)計(jì),之間的設(shè)計(jì)模式以及一些面向?qū)ο蟮乃枷搿?/p>
什么是領(lǐng)域模型?
領(lǐng)域模型是關(guān)于某個(gè)特定業(yè)務(wù)領(lǐng)域的軟件模型。通常,領(lǐng)域模型通過(guò)對(duì)象模型來(lái)實(shí)現(xiàn),這些對(duì)象同時(shí)包含了數(shù)據(jù)和行為,并且表達(dá)了準(zhǔn)確的業(yè)務(wù)含義。
Why DDD?
軟件開(kāi)發(fā)過(guò)程中的問(wèn)題:
- “隨著業(yè)務(wù)的擴(kuò)展,軟件開(kāi)發(fā)投資越來(lái)越大” 團(tuán)隊(duì)的規(guī)模也開(kāi)始變得越來(lái)越大,軟件系統(tǒng)的投資和維護(hù)的成本變得越來(lái)越高。
- “業(yè)務(wù)人員不懂架構(gòu),架構(gòu)師不懂代碼,開(kāi)發(fā)人員不不懂業(yè)務(wù)模型” 當(dāng)團(tuán)隊(duì)中的關(guān)鍵角色誰(shuí)也不懂誰(shuí)的時(shí)候,問(wèn)題來(lái)了。。。
- “重構(gòu)是好的,但什么時(shí)候要重構(gòu)?重構(gòu)到什么樣的架構(gòu)就是夠?的了?” 每個(gè)有追求的團(tuán)隊(duì)都在做重構(gòu),但管理者更關(guān)心,什么時(shí)間必須要重構(gòu)?重構(gòu)的目標(biāo)在哪?
采用DDD的原因:
- 業(yè)務(wù)沉淀,知識(shí)共享
- 業(yè)務(wù)人員及技術(shù)人員之間信息的準(zhǔn)確傳遞
- 幫助業(yè)務(wù)人員與技術(shù)人員自我提高
- DDD同時(shí)提供了戰(zhàn)略設(shè)計(jì)與戰(zhàn)術(shù)設(shè)計(jì)。戰(zhàn)略設(shè)計(jì)幫助我們理解哪些投入是重要的;哪些軟件資產(chǎn)是可以復(fù)用的;哪些人應(yīng)當(dāng)被加入到團(tuán)隊(duì)中。戰(zhàn)術(shù)設(shè)計(jì)則幫助我們創(chuàng)建DDD模型中的各個(gè)部件。
DDD如何幫助我們?
DDD主要關(guān)注三個(gè)方面:
- 將領(lǐng)域?qū)<遗c開(kāi)發(fā)人員聚集到一起,創(chuàng)建一套適用于領(lǐng)域建模的通用語(yǔ)言。通用語(yǔ)言必須在全隊(duì)內(nèi)部達(dá)成一致。
- DDD關(guān)注業(yè)務(wù)戰(zhàn)略。戰(zhàn)略設(shè)計(jì)用于清楚的區(qū)分不同的系統(tǒng)與業(yè)務(wù)關(guān)注點(diǎn);更進(jìn)一步指引我們實(shí)現(xiàn)面向服務(wù)架構(gòu)(SOA)或者業(yè)務(wù)驅(qū)動(dòng)架構(gòu)(BDA)
- 通過(guò)使用戰(zhàn)術(shù)設(shè)計(jì)建模工具,滿足軟件真正的技術(shù)需求。
DDD的業(yè)務(wù)價(jià)值:
- 業(yè)務(wù)得到更準(zhǔn)確的定義與理解
- 領(lǐng)域?qū)<乙材軈⑴c到軟件設(shè)計(jì)中來(lái)
- 更好的用于體驗(yàn)
- 企業(yè)架構(gòu)
- 敏捷、迭代、持續(xù)建模
When DDD?
- 業(yè)務(wù)復(fù)雜度高
- 需求的未知性
- 領(lǐng)域的未知性

處理領(lǐng)域復(fù)雜性
將重要的、復(fù)雜的模型稱(chēng)為核心域(Core Domain)。
將相對(duì)次要的稱(chēng)為支撐子域(Supporting Subdomain)。
貧血領(lǐng)域?qū)ο螅ˋnemic Domian Model)
缺少內(nèi)在行為的領(lǐng)域?qū)ο蟆?/p>
- 業(yè)務(wù)沒(méi)有沉淀在對(duì)應(yīng)的模型中;
- 隨時(shí)間推移,業(yè)務(wù)邏輯被遺忘;代碼風(fēng)險(xiǎn)變高
How DDD?
對(duì)于初步接觸DDD的團(tuán)隊(duì)而言,事件風(fēng)暴工作坊是一個(gè)很好的開(kāi)始。可以參考寫(xiě)過(guò)的一篇事件風(fēng)暴工作坊的實(shí)踐和總結(jié)和網(wǎng)上的一些其他資源。
以下是從DDD的經(jīng)典書(shū)籍中摘錄的一些實(shí)踐方式。
DDD兩大支柱:通用語(yǔ)言(Ubiquitous Language)和限界上下文(Bounded Context)。
通用語(yǔ)言是團(tuán)隊(duì)的共享語(yǔ)言。領(lǐng)域?qū)<遗c開(kāi)發(fā)者使用相同的通用語(yǔ)言進(jìn)行交流。通用語(yǔ)言的更改,就是對(duì)領(lǐng)域模型的更改。
通用語(yǔ)言的缺失將造成高昂的解釋與誤解溝通成本。
限界上下文(Bounded Context)是應(yīng)用程序的一個(gè)概念性邊界,這個(gè)邊界內(nèi)的各種領(lǐng)域?qū)儆凇簿褪峭ㄓ谜Z(yǔ)言,有確定的上下文含義。在邊界之外,這些術(shù)語(yǔ)可能表示不同的意思。
如何制定通用語(yǔ)言?
- 繪制物理模型圖,概念模型圖等,標(biāo)以名字和行為
- 創(chuàng)建一個(gè)包含簡(jiǎn)單定義的術(shù)語(yǔ)表
- 如果不喜歡術(shù)語(yǔ)表,也可以采用其他類(lèi)型的文檔。同時(shí)將那些“不正式的”模型圖也給包括進(jìn)去
- 與團(tuán)隊(duì)其他成員來(lái)檢驗(yàn)成本,并且溝通迭代
TIPS:
- 通用語(yǔ)言通常只在團(tuán)隊(duì)范圍內(nèi)使用,表示一個(gè)單一的領(lǐng)域模型
- 如果試圖創(chuàng)建企業(yè)級(jí)乃至更大范圍的通用語(yǔ)言時(shí),幾乎一定會(huì)失敗
- 通用語(yǔ)言與限界上下文有一對(duì)一的關(guān)系
- 限界上下文也很小,剛好可以容納一個(gè)獨(dú)立業(yè)務(wù)領(lǐng)域使用的通用語(yǔ)言
- 每個(gè)限界上下文有自己的通用語(yǔ)言,和其他限界上下文打交道時(shí),可以通過(guò)上下文映射圖來(lái)集成。
實(shí)現(xiàn)DDD的挑戰(zhàn)
- 創(chuàng)建通用語(yǔ)言時(shí)候,時(shí)間精力的投入
- 持續(xù)的引入領(lǐng)域?qū)<?/li>
- 改變開(kāi)發(fā)者對(duì)領(lǐng)域的思考方式
DDD與敏捷結(jié)合的實(shí)踐
結(jié)合Scrum的思想,DDD也傾向于“測(cè)試先行,逐步改進(jìn)的策略”。
即便再專(zhuān)業(yè)的領(lǐng)域?qū)<遥矡o(wú)法在業(yè)務(wù)初期進(jìn)行完美的設(shè)計(jì)。
開(kāi)發(fā)一個(gè)新的領(lǐng)域?qū)ο髸r(shí),可以采用以下步驟:
- 編寫(xiě)測(cè)試代碼,模擬客戶端使用該領(lǐng)域?qū)ο?/li>
- 創(chuàng)建該領(lǐng)域?qū)ο笠允箿y(cè)試代碼可以編譯通過(guò)
- 對(duì)測(cè)試與領(lǐng)域?qū)ο笾貥?gòu)。測(cè)試能正確的模擬客戶代碼,領(lǐng)域?qū)ο罂梢员砻鳂I(yè)務(wù)行為
- 實(shí)現(xiàn)領(lǐng)域?qū)ο?/li>
- 向團(tuán)隊(duì)成員,包括領(lǐng)域?qū)<?,展示代碼,以保證領(lǐng)域?qū)ο竽苷_的反映通用語(yǔ)言