DDD:架構思想的舊瓶新酒

備份學習

DDD 和 DSL、DCI 的關係是什麼?開發團隊爲何需要 DDD?它與微服務與中臺又有着怎樣的聯繫?目前業界實踐 DDD 最大的問題是什麼?11 月 30 日,在由 ThoughtWorks 舉辦的領域驅動設計峯會 DDD-China 2019 上,InfoQ 記者帶着這些問題對中興通訊資深軟件架構師張曉龍進行了採訪。

 

DDD、DSL 和 DCI

DDD 概念最早提出於 2004 年,作爲一種軟件開發的指導思想,DDD 對軟件開發帶來了諸多可能與方向,張曉龍認爲 DDD 爲軟件開發帶來的好處主要有以下幾點:

  • 首先,最大好處就是所有參與者圍繞一個統一一致的領域模型工作,傳統的分析模型和設計模型不再割裂,不管是做設計、做分析還是寫代碼、寫文檔,腦海中所構建的畫面都是一致的。

  • 第二,DDD 是一個軟件開發過程,它顯式地把領域和設計放到了軟件開發的核心,軟件人員和業務人員被受到同樣的重視,他們合作來構建領域模型,使得軟件的交付質量更高且維護成本更低;

  • 第三,DDD 提出的分層架構,有效分離了業務複雜度和技術複雜度,凸顯了領域模型,使得領域層的代碼和領域模型保持高度一致;

  • 第四,統一語言非常重要,每個概念在各自的上下文中是清晰的無歧義的,同時要控制領域模型的複雜度,於是 DDD 在戰略上提出了分離子域(問題域空間)和拆分 BC(解決方案空間)的模式,BC 間通過 Context Mapping 來集成;

  • 第五,DDD 在戰術層面提出了很多模式(聚合,實體,值對象,服務,工廠,倉儲),對領域模型中的元素進行了分類,並給出了每類元素在領域模型中的職責和特徵,降低了領域模型的構建成本。

張曉龍此前曾在 DDD-China 峯會和 ArchSummit 全球架構師峯會上分別做過《當 DDD 遇上 DSL(Domain-Specific Language)》、《當 DDD 遇上 DCI(Data,Context, Interactive)》的演講,在他看來,DDD 和 DSL、DCI 之間存在極強的關聯性。

DDD 和 DSL 的融合有三點:

  1. 面向領域;

  2. 模型的組裝方式;

  3. 分層架構演進。

DSL 可以看作是在領域模型之上的一層外殼,可以顯著增強領域模型的能力。它的價值主要有兩個,一是提升了開發人員的生產力,二是增進了開發人員與領域專家的溝通。舉個例子:想讓 BA 負責流程契約的設計,該流程契約是一個活文檔,可以跑測試,而 BA 不熟悉宿主語言。於是,我們設計了一種外部 DSL 來專門描述流程契約,對 BA 非常友好,學習成本也很低(不超過 5 分鐘就可以學會),最後發現 BA 很快就廣泛使用了起來。外部 DSL 並不一定要定義新文法,我們直接複用了 plantUML 文法,安裝該插件可以自動生成序列圖,非常棒!對於外部 DSL,需要自己實現一個解析器將 DSL 文法解析成語法樹,再根據語法樹生成語義模型。語義模型可以看作領域模型(嚴格的講語義模型是領域模型的子集),外部 DSL 就是對領域模型的一種組裝方式。

DCI 的作用主要體現在兩方面:

首先,DCI 助力 DDD 戰術設計:

  1. 顯式地對 ROLE 建模,解決了貧血模型與充血模型之爭;

  2. 一個聚合可以支持哪些 ROLE,一個 ROLE 可以由哪些聚合扮演,一個場景下哪些聚合要扮演哪些角色;

  3. 當 Aggregate 內部實體行爲比較多時可以嵌套使用 DCI 來拆分和組合;

其次,DCI 助力 DDD 代碼落地:

  1. 對象就是 Data,Client 爲 Context,對象在 Client 中的行爲就是 ROLE。

  2. 根據正交設計原則得到小類(素材庫),根據多重繼承(only C++)或依賴注入來組合素材,不管是行爲類還是數據類,都按 Role 的方式來組合,對像僅僅組合 Role 並注入依賴;

  3. 小類大對象:類作爲一種模塊化手段,遵循高內聚,低耦合,讓軟件易於應對變化;對象作爲一種領域對象的的直接映射,解決了過多的類帶來的可理解性問題,讓領域可以指導設計,設計真正反映領域;領域對象需要真正意義上的生命週期管理。

張曉龍認爲,DCI 對一些開發人員的影響可能比 DDD 和 DSL 還大,因爲開發人員每天都在不斷倒騰代碼,想讓代碼的組合性更強,以便快速應對需求的變化。

 

開發團隊真的需要 DDD

DDD 思想貫穿了整個軟件開發的生命週期,包括對需求的分析、建模、架構、設計,和最終的代碼實現,甚至對代碼的測試與重構。代碼是業務的核心資產,不管是否特性團隊,開發團隊肯定是代碼的編寫者和守護者。

對於開發團隊而言,需要關注以下幾點:

  • 首先是統一語言,讓團隊成員可以做到無障礙的溝通,不管是什麼角色都能基於同樣的畫面進行討論;

  • 其次是團隊中各個角色都圍繞領域模型開展工作;

  • 第三是代碼物理設計容易標準化,比如說在分層設計時,基礎設施層怎麼設計,應用層怎麼設計,DTO 應該放在哪兒,領域層中各個建模元素如何組織?

更進一步,在分層架構裏,應用層更加關注橫切面的東西,比如說要上報一個告警,要給用戶發送一個 Email,這些最好都集中放到應用層裏面。但觸發是在領域層發生的,應用層怎麼知道?通過領域事件來實現依賴反轉,即應用層訂閱領域事件,領域層發佈領域事件。

在中興通訊,核心業務屬於通信行業,DDD 的應用場景跟互聯網企業有着很大差別:

  1. 嵌入式軟件;

  2. 兼業務複雜性和技術複雜性;

  3. 軟件規模大,功能複雜,特性交叉;

  4. 高質量,高性能,高可靠等要求。

張曉龍舉例提到,中興通訊在開發團隊中實踐 DDD 的經驗具體而言有以下幾點:

  1. 領域專家下團隊,和團隊一起交流和協作;

  2. 教練指導,開展戰訓營,定期 review;

  3. 架構、設計、編碼和工程實踐:(1)DCI,DSL,正交設計,組合式設計;(2)編碼規範和紀律;(3)嵌入式 C/C++ 最佳實踐;(4)軟件工程能力:開發者測試,小步安全流暢的重構,持續交付流水線,每日 Code Review。

 

DDD 與微服務

DDD 概念提出距今已經有 15 年的歷史,前十年時間都一直處於不溫不火的狀態,而在最近幾年纔開始大行其道。張曉龍表示,中興通訊在 2012-2015 年期間也有過一些成功的案例,但對於整個業界來說了解的人並不多。他拿 DDD-China 峯會舉例解釋:這次峯會的參會者有 500 人的規模,而我們假設峯會在 2015 年之前舉辦的話,估計參會者不會超過 100 人。因此,我們可以斷定是微服務的熱風讓人們重新發現了領域驅動設計的價值。

微服務架構從提出以來一直沒有很好的理論支撐如何合理地劃分服務邊界,人們常常爲服務要劃分多大而爭吵不休。而 DDD 被發現恰好可以彌補微服務的營養不良:(1)服務最大不要大過一個 BC,否則服務內可能會存在有歧義的領域概念;(2)服務最小不要小過一個聚合,否則會引入分佈式事務的複雜度;(3)服務間最好通過 Domain Event 來進行交互,這樣可以讓服務保持鬆耦合。微服務和 DDD 的結合,讓微服務架構看起來似乎更加穩健了。

“微服務就像是 DDD 的心上人,使得 DDD 真正煥發起了青春。”張曉龍這樣解釋。

對於業界目前流行的中臺概念,張曉龍同樣也有自己的看法:

中臺和 DDD 不是同一個層面的東西,不能爲了把它們聯繫在一起,而強行找相似點。中臺實際上就是多條業務線的共同需求,比如對於滴滴公司來說,快車、專車和出租車等業務都是微服務架構,這些業務的很多服務是相似的,考慮將這些服務從各個前臺下沉到統一的平臺,這個平臺就是中臺。中臺要考慮各個前臺的需求,所以複雜性變高了。

中臺是一種企業級的架構模式,從企業全局整體視角來看架構全貌,而 DDD 是一種主流的軟件開發方法,用來應對軟件的核心複雜性。中臺架構可以看作是微服務架構的延伸和發展,服務複雜性很高,所以更需要用 DDD 的方式去設計和建模,但二者之間並不是相同層面的概念。

 

DDD 的困局

最近幾年 DDD 的火爆也給業界開發團隊帶來了一些迷思,爲什麼我的 DDD 推行不下去?爲什麼我的 DDD 做起來總是跟敏捷一樣,最後都變了味?

張曉龍總結了 DDD 目前面臨的幾大困局:

  • 首先是領域案例面比較窄。目前業界的 DDD 實踐案例並不多,而且很多案例是偏向互聯網領域的,對於工業領域、嵌入式領域和操作系統領域基本沒有涉及;

  • 第二,DDD 書籍非常少,而且大多數書籍是以 Java 或 C#寫的。如果開發團隊用的是 C、C++、Python 或 Go 語言,基本沒有可參考的書籍,難度也就更大一些(尤其是 C 和 C++);

  • 第三,各個巨頭公司,比如 Google,微軟,BAT 等,很少組織、參與或贊助 DDD 峯會,沒有形成引導作用,業界自然也就少有跟隨效應;

  • 第四,開發團隊要麼找不到領域專家,要麼領域專家無法與開發團隊長時間保持溝通,導致實踐中出現偏差;

  • 第五,DDD 落地有一定的門檻,對開發者的技能和素質都有較高的要求。

針對以上幾大困局,張曉龍也給出了自己的解決方案:

  1. 培訓 OOA、OOD 和 OOP 的基本知識,並實戰演練,不斷彌補與高手的 gap ;

  2. 領域專家和團隊一起工作,確保大家頭腦中的畫面是一致的;

  3. DDD 建模要有文檔交付物,並和代碼同步演進,以便對代碼不熟悉的人員也能看到並理解領域驅動設計成果的全貌。

軟件開發沒有銀彈,DDD 也不是萬能的。如果開發團隊真的決定用 DDD 的思想指導軟件開發,就一定要跟隨時代的腳步,吃透 DDD 這個舊瓶裏裝的新酒。

 

 

 

 

發佈了213 篇原創文章 · 獲贊 26 · 訪問量 81萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章