輕鬆學DDD之一:模型驅動設計
我是2012年開始接觸到DDD(領域驅動設計)的, 後續陸陸續續研讀過幾遍Eric的大做《領域驅動設計:軟件核心複雜性應對之道》,也使用DDD重構過一個項目。總的感覺是DDD的一些概念比較晦澀難懂,很難掌握,所以想寫個系列短文,但願能用通俗易懂的語言幫助你們更輕鬆更深刻地理解DDD。文章不少都是我我的體會和理解,不免有錯誤,但願你們能及時指正,共同提升。
本文是系列短文第一篇,介紹DDD的起始概念模型驅動設計。算法
1. 軟件開發方法回顧
軟件開發能夠看作是一個把用戶需求轉換爲可正確運行的程序的過程,其中最關鍵部分是把用戶需求轉換成代碼。咱們要學習的DDD實際上就是一種軟件開發方法,它相比以前的軟件開發方法,能更好地應對軟件的核心複雜度。爲了能更好的理解它,咱們先回顧下以前的軟件開發方法及其存在問題。
在上世紀60年代,因爲需求簡單,軟件開發以做坊式開發爲主。可是隨着硬件的飛速發展,軟件複雜度也迅速激增,終於在70年引起了軟件危機。爲了應對危機,業界借鑑成熟生產製造管理方法,發展出以「過程爲中心」的瀑布式開發方法。數據庫
1.1 瀑布式開發
瀑布式開發把整個軟件開發過程劃分爲需求分析、方案設計、編碼、測試等階段,但願以這種相似工業流水線的做業分工方式來控制軟件開發的風險和成本。編程
- 需求分析:經過需求分析咱們須要明確用戶想要的功能,會怎麼來使用這些功能,經過這些功能能獲得什麼價值;消除用戶需求中的二義性、相互矛盾的地方;細化各類正常/異常功能場景,驗收準則,性能、可靠性等非功能性約束。
- 設計:在設計階段須要根據需求分析結果決定軟件的整體實現方案。在系統設計階段會肯定子系統劃分,進行開發、運行平臺、數據庫等關鍵技術選型;在方案設計階段則會明確模塊劃分,模塊內部架構,協做流程,關鍵算法等。
- 編碼:根據設計完成代碼編寫。
- 測試:測試軟件是否知足用戶需求。

上圖展現了應用瀑布式開發方法的軟件開發流程,咱們能夠看到這種方法能夠經過專業分工和流水做業來分解複雜度和提高效率,這在在必定程序上緩解了軟件危機。可是與工業生產不一樣,軟件需求和開發過程存在不少不肯定因素,所以這種方法在應用過程當中也發現了不少問題。
- 每一個需求的各階段由不一樣的人依次完成,階段之間用文檔傳遞知識,各階段之間缺少溝通和反饋,錯誤和理解誤差不能及時糾正,每每影響軟件的正確交付。
- 每一個需求輸出各自的分析、設計文檔,沒有整合。隨着軟件規模增加,分析和設計會喪失對軟件總體性的把握,進而影響分析和設計的全面性和正確性。
- 因爲缺少反饋,分析、設計和代碼之間的差別會愈來愈大,耗費大量人力編寫的分析設計文檔會逐步失去價值,協做會愈來愈困難,軟件也愈來愈難以定期正確交付。
爲了解決瀑布式開發的開發效率低下、響應需求速度慢的問題,輕量級的,更能適應變化的敏捷軟件開發方法被廣泛承認並迅速流行起來,極限編程就是其中的一種。架構
2 極限編程

XP主要由13個實踐構成,是一種近螺旋式的開發方法。它將複雜的開發過程分解爲一個個相對比較簡單的小週期;經過積極的交流、反饋以及其它一系列的方法,開發人員和客戶能夠很是清楚開發進度、變化、待解決的問題和潛在的困難等,並根據實際狀況及時地調整開發過程。
爲了與瀑布式開發作對比,咱們把XP簡單理解爲下圖:

經過上圖咱們能夠看到,XP沒有劃分分析、設計、編碼和測試等階段,需求能夠在一個週期爲1~2周的迭代中快速交付。XP之因此能作到快速交付,有以下幾個緣由:ide
- 客戶、業務專家、開發、測試你們坐在一塊兒完成需求開發,面對面溝通取代了文檔,節省了文檔編寫、維護的工做量。
- 經過簡單設計、TDD、ATDD、CI等工程實踐保證分析、設計、編碼、測試之間更快速的反饋和充分的並行化,有效縮短了開發週期。
- 經過不斷重構代碼來保證代碼更加簡潔,能更好地反應軟件的核心複雜度。
- 經過結對、代碼集體全部權、系統隱喻、編碼規範、完整團隊促進了技能和知識的共享。
XP很是反對作預先設計,需求分析與設計會被拆分到用戶故事乃至TDD的小步迭代中去作,在每一個小迭代中代碼只會根據當前需求簡單實現;當在後續迭代過程當中發現代碼難以知足新需求時,須要經過重構來增長代碼對新需求的適應性,以便可以快速實現新需求。這種作法當然能帶來不少好處,可是也存在一些缺陷:性能
- 若是軟件複雜度高,需求之間有着複雜的關聯,開發在沒有很理解業務邏輯就貿然開始寫代碼,會帶來很是大的重構成本,甚至於須要重寫。
- 只有代碼承載業務共識,維護業務共識的成本高,最終致使難以維持業務共識。你們交流的共識除了存在於頭腦中外,只存在於代碼中,這對於代碼的業務表達力和專家/客戶的代碼理解能力都提出了很是高的要求,最終可能致使你們對於業務的理解的差別會愈來愈大。
3. 模型驅動設計

爲了彌補XP在應對軟件核心複雜度的缺陷,eric在2003年提出了一種新的方法,他認爲咱們須要引入領域模型並圍繞它來作需求分析和軟件設計,這就是模型驅動開發。這一論述有如下幾個要點:學習
- 模型是統一的,它反映了領域的核心複雜度,而不是領域內每一個需求面面俱到的細節。一些不涉及軟件核心價值且不影響全局的細節能夠在放在迭代中考慮,相關知識沉澱在代碼中便可,就像XP作的那樣;可是涉及軟件核心價值,或者影響全局的業務邏輯須要歸入領域模型中作統一細緻的分析,並在軟件生命週期內不斷地演進精煉。
- 模型是交流和協做的中樞。客戶、業務專家、開發、測試等各類角色一塊兒參與構建模型的,你們基於共同的模型來作交流和協做。
- 模型與代碼是綁定的。代碼修改能方便地同步到模型,模型修改也能方便地同步代碼。這要求模型不僅體現問題域的知識和約束,也能體現實現域的知識和約束;涉及業務邏輯的代碼須要不斷提煉,剝離技術實現細節,以便能很好地表達模型。
最後總結下,模型驅動設計經過對軟件核心複雜度的統一建模,解決了瀑布式開發在需求分析、軟件設計上的溝通、反饋和知識整合上的缺陷,也解決了XP極簡主義設計存在的缺陷。
文本重點敘述了咱們爲何須要領域模型,領域模型構建須要注意的幾個基本原則,可是具體要怎麼來構建領域模型呢?請看下一篇《輕鬆學DD之二:如何高效消化知識》。測試