輕松學(xué)DDD之一:模型驅(qū)動(dòng)設(shè)計(jì)
我是2012年開始接觸到DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))的健芭, 后續(xù)讀過幾遍Eric的大作《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì):軟件核心復(fù)雜性應(yīng)對(duì)之道》静盅,也用DDD重構(gòu)過項(xiàng)目。總的感受是DDD的一些概念比較晦澀難懂,很難掌握局齿,因此想寫個(gè)系列短文,希望能用通俗易懂的語言幫助大家更輕松更深入地理解DDD橄登。文章很多都是我個(gè)人體會(huì)和理解,難免有錯(cuò)誤讥此,希望大家能及時(shí)指正拢锹,共同提高。
本文是系列短文第一篇萄喳,介紹DDD的起始概念**模型驅(qū)動(dòng)設(shè)計(jì)**卒稳。
1. 軟件開發(fā)方法回顧
軟件開發(fā)可以看做是一個(gè)把用戶需求轉(zhuǎn)換為可正確運(yùn)行的程序的過程,其中最關(guān)鍵部分是把用戶需求轉(zhuǎn)換成代碼他巨。我們要學(xué)習(xí)的DDD實(shí)際上就是一種軟件開發(fā)方法充坑,它相比之前的軟件開發(fā)方法,能更好地應(yīng)對(duì)軟件的核心復(fù)雜度染突。為了能更好的理解它捻爷,我們先回顧下之前的軟件開發(fā)方法及其存在問題。
在上世紀(jì)60年代份企,由于需求簡(jiǎn)單也榄,軟件開發(fā)以作坊式開發(fā)為主。但是隨著硬件的飛速發(fā)展司志,軟件復(fù)雜度也迅速激增甜紫,終于在70年引發(fā)了軟件危機(jī)。為了應(yīng)對(duì)危機(jī)骂远,業(yè)界借鑒成熟生產(chǎn)制造管理方法囚霸,發(fā)展出以“過程為中心”的瀑布式開發(fā)方法。
1.1 瀑布式開發(fā)
瀑布式開發(fā)把整個(gè)軟件開發(fā)過程劃分為需求分析激才、方案設(shè)計(jì)拓型、編碼和泌、測(cè)試等階段镐躲,希望以這種類似工業(yè)流水線的作業(yè)分工方式來控制軟件開發(fā)的風(fēng)險(xiǎn)和成本。
? 1. **需求分析**:通過需求分析我們需要明確用戶想要的功能歧寺,會(huì)怎么來使用這些功能钞脂,通過這些功能能得到什么價(jià)值揣云;消除用戶需求中的二義性、相互矛盾的地方冰啃;細(xì)化各種正常/異常功能場(chǎng)景邓夕,驗(yàn)收準(zhǔn)則刘莹,性能、可靠性等非功能性約束焚刚。
? 2. **設(shè)計(jì)**:在設(shè)計(jì)階段需要根據(jù)需求分析結(jié)果決定軟件的總體實(shí)現(xiàn)方案点弯。在系統(tǒng)設(shè)計(jì)階段會(huì)確定子系統(tǒng)劃分,進(jìn)行開發(fā)矿咕、運(yùn)行平臺(tái)抢肛、數(shù)據(jù)庫等關(guān)鍵技術(shù)選型;在方案設(shè)計(jì)階段則會(huì)明確模塊劃分碳柱,模塊內(nèi)部架構(gòu)捡絮,協(xié)作流程,關(guān)鍵算法等莲镣。
? 3. **編碼**:根據(jù)設(shè)計(jì)完成代碼編寫福稳。
? 4. **測(cè)試**:測(cè)試軟件是否滿足用戶需求。
上圖展示了應(yīng)用瀑布式開發(fā)方法的軟件開發(fā)流程瑞侮,我們可以看到這種方法可以通過專業(yè)分工和流水作業(yè)來分解復(fù)雜度和提升效率的圆,這在在一定程序上緩解了軟件危機(jī)。但是與工業(yè)生產(chǎn)不同半火,軟件需求和開發(fā)過程存在很多不確定因素越妈,因此這種方法在應(yīng)用過程中也發(fā)現(xiàn)了很多問題。
? 1. 每個(gè)需求的各階段由不同的人依次完成慈缔,階段之間用文檔傳遞知識(shí)叮称,各階段之間缺乏溝通和反饋,錯(cuò)誤和理解偏差不能及時(shí)糾正藐鹤,往往影響軟件的正確交付瓤檐。
? 2. 每個(gè)需求輸出各自的分析、設(shè)計(jì)文檔娱节,沒有整合挠蛉。隨著軟件規(guī)模增長(zhǎng),分析和設(shè)計(jì)會(huì)喪失對(duì)軟件整體性的把握肄满,進(jìn)而影響分析和設(shè)計(jì)的全面性和正確性谴古。
? 3. 由于缺乏反饋,分析稠歉、設(shè)計(jì)和代碼之間的差異會(huì)越來越大掰担,耗費(fèi)大量人力編寫的分析設(shè)計(jì)文檔會(huì)逐步失去價(jià)值,協(xié)作會(huì)越來越困難怒炸,軟件也越來越難以按期正確交付带饱。
為了解決瀑布式開發(fā)的開發(fā)效率低下、響應(yīng)需求速度慢的問題,輕量級(jí)的勺疼,更能適應(yīng)變化的敏捷軟件開發(fā)方法被普遍認(rèn)可并迅速流行起來教寂,極限編程就是其中的一種。
2 極限編程
XP主要由13個(gè)實(shí)踐構(gòu)成执庐,是一種近螺旋式的開發(fā)方法酪耕。它將復(fù)雜的開發(fā)過程分解為一個(gè)個(gè)相對(duì)比較簡(jiǎn)單的小周期;通過積極的交流轨淌、反饋以及其它一系列的方法迂烁,開發(fā)人員和客戶可以非常清楚開發(fā)進(jìn)度、變化猿诸、待解決的問題和潛在的困難等婚被,并根據(jù)實(shí)際情況及時(shí)地調(diào)整開發(fā)過程。
為了與瀑布式開發(fā)做對(duì)比梳虽,我們把XP簡(jiǎn)單理解為下圖:
通過上圖我們可以看到,XP沒有劃分分析灾茁、設(shè)計(jì)窜觉、編碼和測(cè)試等階段,需求可以在一個(gè)周期為1~2周的迭代中快速交付北专。XP之所以能做到快速交付禀挫,有如下幾個(gè)原因:
? 1. 客戶、業(yè)務(wù)專家拓颓、開發(fā)语婴、測(cè)試大家坐在一起完成需求開發(fā),面對(duì)面溝通取代了文檔驶睦,節(jié)省了文檔編寫砰左、維護(hù)的工作量。
? 2. 通過簡(jiǎn)單設(shè)計(jì)场航、TDD缠导、ATDD、CI等工程實(shí)踐保證分析溉痢、設(shè)計(jì)僻造、編碼、測(cè)試之間更快速的反饋和充分的并行化孩饼,有效縮短了開發(fā)周期髓削。
?3. 通過不斷重構(gòu)代碼來保證代碼更加簡(jiǎn)潔,能更好地反應(yīng)軟件的核心復(fù)雜度镀娶。
?4. 通過結(jié)對(duì)立膛、代碼集體所有權(quán)、系統(tǒng)隱喻汽畴、編碼規(guī)范旧巾、完整團(tuán)隊(duì)促進(jìn)了技能和知識(shí)的共享耸序。
XP非常反對(duì)做預(yù)先設(shè)計(jì),需求分析與設(shè)計(jì)會(huì)被拆分到用戶故事乃至TDD的小步迭代中去做鲁猩,在每個(gè)小迭代中代碼只會(huì)根據(jù)當(dāng)前需求簡(jiǎn)單實(shí)現(xiàn)坎怪;當(dāng)在后續(xù)迭代過程中發(fā)現(xiàn)代碼難以滿足新需求時(shí),需要通過重構(gòu)來增加代碼對(duì)新需求的適應(yīng)性廓握,以便能夠快速實(shí)現(xiàn)新需求搅窿。這種做法固然能帶來很多好處,但是也存在一些缺陷:
? 1. 如果軟件復(fù)雜度高隙券,需求之間有著復(fù)雜的關(guān)聯(lián)男应,開發(fā)在沒有很理解業(yè)務(wù)邏輯就貿(mào)然開始寫代碼,會(huì)帶來非常大的重構(gòu)成本娱仔,甚至于需要重寫沐飘。
? 2. 只有代碼承載業(yè)務(wù)共識(shí),維護(hù)業(yè)務(wù)共識(shí)的成本高牲迫,最終導(dǎo)致難以維持業(yè)務(wù)共識(shí)耐朴。大家交流的共識(shí)除了存在于頭腦中外,只存在于代碼中盹憎,這對(duì)于代碼的業(yè)務(wù)表達(dá)力和專家/客戶的代碼理解能力都提出了非常高的要求,最終可能導(dǎo)致大家對(duì)于業(yè)務(wù)的理解的差異會(huì)越來越大筛峭。
3. 模型驅(qū)動(dòng)設(shè)計(jì)
為了彌補(bǔ)XP在應(yīng)對(duì)軟件核心復(fù)雜度的缺陷,eric在2003年提出了一種新的方法陪每,他認(rèn)為我們需要引入領(lǐng)域模型并圍繞它來做需求分析和軟件設(shè)計(jì)影晓,這就是模型驅(qū)動(dòng)開發(fā)。這一論述有以下幾個(gè)要點(diǎn):
? 1. **模型是統(tǒng)一的檩禾,它反映了領(lǐng)域的核心復(fù)雜度挂签,而不是領(lǐng)域內(nèi)每個(gè)需求面面俱到的細(xì)節(jié)。**一些不涉及軟件核心價(jià)值且不影響全局的細(xì)節(jié)可以在放在迭代中考慮锌订,相關(guān)知識(shí)沉淀在代碼中即可竹握,就像XP做的那樣;但是涉及軟件核心價(jià)值辆飘,或者影響全局的業(yè)務(wù)邏輯需要納入領(lǐng)域模型中做統(tǒng)一細(xì)致的分析啦辐,并在軟件生命周期內(nèi)不斷地演進(jìn)精煉。
? 2. **模型是交流和協(xié)作的中樞蜈项。**客戶芹关、業(yè)務(wù)專家、開發(fā)紧卒、測(cè)試等各種角色一起參與構(gòu)建模型的侥衬,大家基于共同的模型來做交流和協(xié)作。
? 3. **模型與代碼是綁定的。**代碼修改能方便地同步到模型轴总,模型修改也能方便地同步代碼直颅。這要求模型不只體現(xiàn)問題域的知識(shí)和約束,也能體現(xiàn)實(shí)現(xiàn)域的知識(shí)和約束怀樟;涉及業(yè)務(wù)邏輯的代碼需要不斷提煉功偿,剝離技術(shù)實(shí)現(xiàn)細(xì)節(jié),以便能很好地表達(dá)模型往堡。
最后總結(jié)下械荷,模型驅(qū)動(dòng)設(shè)計(jì)通過對(duì)軟件核心復(fù)雜度的統(tǒng)一建模,解決了瀑布式開發(fā)在需求分析虑灰、軟件設(shè)計(jì)上的溝通吨瞎、反饋和知識(shí)整合上的缺陷,也解決了XP極簡(jiǎn)主義設(shè)計(jì)存在的缺陷穆咐。
文本重點(diǎn)敘述了我們?yōu)槭裁葱枰I(lǐng)域模型颤诀,領(lǐng)域模型構(gòu)建需要注意的幾個(gè)基本原則,但是具體要怎么來構(gòu)建領(lǐng)域模型呢对湃?請(qǐng)期望下一篇《輕松學(xué)DD之二:領(lǐng)域知識(shí)消化》着绊。