關(guān)于我們
書單推薦
新書推薦
|
深入實(shí)踐 DDD:以 DSL 驅(qū)動復(fù)雜軟件開發(fā) 本書是擁有二十年商業(yè)軟件開發(fā)經(jīng)驗(yàn)及十年技術(shù)管理經(jīng)驗(yàn)的資深技術(shù)專家嘔心瀝血之作,也是目前市場上少有的闡述如何通過使用領(lǐng)域?qū)S谜Z言(DSL)實(shí)現(xiàn)領(lǐng)域驅(qū)動設(shè)計(DDD)的圖書。 書中首先帶領(lǐng)讀者重溫DDD在戰(zhàn)術(shù)設(shè)計層面及戰(zhàn)略設(shè)計層面上的部分重要概念,并簡要介紹了自DDD社區(qū)興起的一些軟件架構(gòu)模式。然后闡述如何設(shè)計一門DDD原生的DSL,包括這個DSL的規(guī)范支持哪些特性、如何幫助團(tuán)隊(duì)描述領(lǐng)域模型的方方面面、這些特性的選擇基于何種考量等。 然后在此基礎(chǔ)上詳細(xì)講解了如何使用技術(shù)工具將描述領(lǐng)域模型的DSL文檔直接轉(zhuǎn)化為可以工作的軟件代碼,在這個過程中結(jié)合諸多來自商業(yè)軟件開發(fā)工作中的真實(shí)案例,展示并分析了大量的關(guān)鍵代碼,讓讀者可以深入地了解制造那些基于DSL的DDD技術(shù)工具的秘密。 之后講述了一些建模案例,并探討了一些與DDD相關(guān)的其他話題,對讀者開拓技術(shù)思維、更深刻地理解DDD有所助益。 適讀人群 :1. 產(chǎn)品經(jīng)理與系統(tǒng)分析師。產(chǎn)品經(jīng)理不應(yīng)該僅僅關(guān)注軟件的界面原型、用戶體驗(yàn),產(chǎn)品經(jīng)理需要保證團(tuán)隊(duì)所開發(fā)的是 “正確的軟件”。正確的軟件應(yīng)該邏輯自洽,功能處處傳達(dá)出那個 (1)領(lǐng)域驅(qū)動設(shè)計里程碑之作,資深技術(shù)專家兼技術(shù)管理者二十年工作經(jīng)驗(yàn)結(jié)晶 (2)深度解讀DDD思想,揭示使用 DSL實(shí)現(xiàn)DDD快速落地的方法與技巧,緩解復(fù)雜軟件開發(fā)之痛 【為什么要寫這本書】 2004 年,DDD(領(lǐng)域驅(qū)動設(shè)計)這一軟件開發(fā)的方法與愿景經(jīng)由建模專家 Eric Evans 的經(jīng)典著作Domain-Driven Design: Tackling Complexity in the Heart of Software 正式面世,當(dāng)即獲得了廣泛關(guān)注和高度評價。16 年過去了,我在網(wǎng)上看到越來越多關(guān)于 DDD的文章和討論。為什么我們現(xiàn)在還不停地討論 DDD?為什么DDD仍然如此重要? 在商業(yè)組織中,主張“技術(shù)為業(yè)務(wù)服務(wù)”的企業(yè)總可以在理論上立于不敗之地。誠然,DDD主張在軟件項(xiàng)目中把領(lǐng)域本身作為關(guān)注的焦點(diǎn)(換句話說就是技術(shù)人員要懂業(yè)務(wù))符合這種思想,但真正難能可貴的是,DDD提供了切實(shí)可行的應(yīng)對軟件核心復(fù)雜性的方法。 實(shí)踐證明,DDD 提出的方法不僅行之有效,而且歷久彌新。關(guān)于這一點(diǎn),我想從當(dāng)今 IT 業(yè)界的熱詞“云原生”“中臺”“產(chǎn)業(yè)互聯(lián)網(wǎng)”說起。 什么是云原生?云原生計算基金會(Cloud Native Computing Foundation,CNCF)對云原生的定義是: 云原生技術(shù)有利于各組織在公有云、私有云和混合云等新型動態(tài)環(huán)境中構(gòu)建和運(yùn)行可彈性擴(kuò)展的應(yīng)用。云原生的代表技術(shù)包括容器、服務(wù)網(wǎng)格、微服務(wù)、不可變基礎(chǔ)設(shè)施和聲明式 API。 這些技術(shù)能夠構(gòu)建容錯性好、易于管理和便于觀察的松耦合系統(tǒng)。結(jié)合可靠的自動化手段,云原生技術(shù)使工程師能夠輕松地對系統(tǒng)做出頻繁和可預(yù)測的重大變更。 而阿里云發(fā)布的《云原生架構(gòu)白皮書》 對云原生架構(gòu)的定義是: 從技術(shù)的角度看,云原生架構(gòu)是基于云原生技術(shù)的一組架構(gòu)原則和設(shè)計模式的集合,旨在將云應(yīng)用中的非業(yè)務(wù)代碼部分進(jìn)行最大化剝離,從而讓云設(shè)施接管應(yīng)用中原有的大量非功能特性(如彈性、韌性、安全、 可觀測性、灰度等),使業(yè)務(wù)不再有非功能性業(yè)務(wù)中斷困擾的同時,具備輕量、敏捷、高度自動化的特點(diǎn)。 看了這些定義,你是否還是覺得迷惑?打開CNCF的“l(fā)andscape”頁面——里面有很多的項(xiàng)目和成員,難怪有人說云原生是一個“營銷詞語”。在這個頁面中,在 Members(成員)這個標(biāo)簽頁的左邊,Serverless 獨(dú)占了一個標(biāo)簽頁,十分顯眼。 廣泛認(rèn)同的Serverless 架構(gòu)是指這樣的應(yīng)用設(shè)計:與第三方的后端即服務(wù)(Backend as a Service,BaaS)交互;在函數(shù)即服務(wù)(Function as a Service,F(xiàn)aaS)平臺上運(yùn)行函數(shù)式業(yè)務(wù)代碼,一般來說,它們是在受管理的、臨時性的容器中執(zhí)行的。 雖然新出現(xiàn)的基于容器的 Serverless 平臺,比如 Knative,可以運(yùn)行開發(fā)人員使用傳統(tǒng)方式開發(fā)的應(yīng)用,但 FaaS 仍然是 Serverless 中最重要、最具代表性的產(chǎn)品形態(tài),因?yàn)樗屛覀円砸环N不同于傳統(tǒng)的方式思考技術(shù)架構(gòu)。 FaaS 中的“Function”就是不依賴特定框架和類庫的最純粹的業(yè)務(wù)代碼——這是真正為業(yè)務(wù)帶來價值的東西?梢哉f,F(xiàn)aaS在將云應(yīng)用中的非業(yè)務(wù)代碼部分進(jìn)行最大化剝離方面做到了極致。我認(rèn)為它是云原生“皇冠上的明珠”。 不過,大家普遍認(rèn)為當(dāng)前FaaS更適合開發(fā)事件驅(qū)動風(fēng)格的、處理少數(shù)幾個事件類型的應(yīng)用組件,而不適合開發(fā)傳統(tǒng)的具有很多入口的同步請求/響應(yīng)風(fēng)格的應(yīng)用組件。也就是說,如果你想問:“能不能基于 FaaS 做出一個 SAP ERP?”目前可能大多數(shù)人給你的答案會是“NO”。 但是我想給你的答案是“YES”!因?yàn)橐脒_(dá)到這個目標(biāo),我們需要克服的所有障礙都不屬于 FaaS 的固有缺點(diǎn),而是當(dāng)前FaaS 的實(shí)現(xiàn)缺陷,比如啟動延遲、集成測試、調(diào)試、交付、監(jiān)控與觀測等方面的問題。 我認(rèn)為,以 DDD 方法實(shí)現(xiàn)的應(yīng)用可以極大地降低 FaaS 處理這些問題的難度,甚至可以直接忽視某些問題(因?yàn)樗鼈儗σ?DDD 方法實(shí)現(xiàn)的應(yīng)用來說不是問題)。具體而言,我們可以使用 DDD 的聚合概念來切分應(yīng)用組件,每個聚合一個小組件,它們可以很快地被 FaaS 平臺“拉起”。這些高度內(nèi)聚的小組件是更復(fù)雜的應(yīng)用組件(比如說領(lǐng)域服務(wù))的構(gòu)造塊。我們可以使用興起于 DDD 社區(qū)的 Event Sourcing(事件溯源,ES)模式,保證應(yīng)用狀態(tài)的每一次變更都會發(fā)布領(lǐng)域事件,并以富含業(yè)務(wù)語義的事件驅(qū)動其他應(yīng)用組件運(yùn)行。比如,命令查詢職責(zé)分離(Command Query Responsibility Segregation,CQRS)模式中的 Denormalizer(去規(guī)范化器)組件就可以訂閱、消費(fèi)這些事件,為前端應(yīng)用構(gòu)建友好的查詢視圖——這些都是 DDD 社區(qū)在開發(fā)嚴(yán)肅的商業(yè)軟件時一直在做的事情。如果之前你沒有接觸過聚合、ES、CQRS,也許難以理解上面所說的內(nèi)容,不過沒關(guān)系,讀完本書,我相信你就清楚了。 再說“中臺”這個熱詞。以我的理解,中臺是將可復(fù)用的代碼抽取到一個平臺中,作為大家共用的軟件組件,它是服務(wù)于前臺的規(guī);瘎(chuàng)新。中臺(這里主要指業(yè)務(wù)中臺)想要好用,必須具備“反映對領(lǐng)域的深度認(rèn)知”的軟件模型,甚至在某種程度上需要“過度設(shè)計”,并且絕對有必要維護(hù)良好的概念完整性,構(gòu)建所謂的企業(yè)級業(yè)務(wù)架構(gòu)——這些都是 DDD 可以大展身手的地方。 關(guān)于“產(chǎn)業(yè)互聯(lián)網(wǎng)即將進(jìn)入黃金時代”的說法,大多是眾多傳統(tǒng)企業(yè)希望借力最新的信息化,特別是互聯(lián)網(wǎng)工具(即所謂“互聯(lián)網(wǎng)+”),提升內(nèi)部效率和對外服務(wù)的能力。傳統(tǒng)產(chǎn)業(yè)中的很多領(lǐng)域概念和業(yè)務(wù)流程并不一定為普通的開發(fā)者所熟知——這與“消費(fèi)互聯(lián)網(wǎng)”不同,顯然人人都是消費(fèi)者。所以,傳統(tǒng)產(chǎn)業(yè)的信息化急需可以快速梳理并深刻地認(rèn)知領(lǐng)域,以及能構(gòu)建高質(zhì)量領(lǐng)域模型的技術(shù)人才。DDD 可以說是技術(shù)人員升職加薪的“神兵利器”。 我在工作中看到的情況是,越來越多的技術(shù)人員在自己的求職簡歷上寫上了“熟悉(或精通)DDD”的描述。確實(shí),Eric Evans 的經(jīng)典著作以抽象、凝練著稱,可謂字字珠璣,甚至很多資深技術(shù)人員都不能領(lǐng)悟其中玄妙。所以,我也認(rèn)同掌握 DDD 是一件足以讓技術(shù)人員引以為傲的事情。 可以說,DDD 是公認(rèn)的解決軟件核心復(fù)雜性的“大殺器”。但是,在軟件開發(fā)中實(shí)踐 DDD 是需要付出相當(dāng)大的成本的。也就是說,大家的普遍看法是:實(shí)踐 DDD 是一個先苦后甜的過程,一個項(xiàng)目要不要采用DDD,最好先看看它值不值得。 但是一個項(xiàng)目值不值得使用 DDD 有時不好判斷。大項(xiàng)目往往是由小項(xiàng)目發(fā)展而來的,很多從小項(xiàng)目演化而來的大系統(tǒng)最終變成開發(fā)團(tuán)隊(duì)的噩夢,噩夢的根源幾乎無一例外地在于軟件的概念完整性遭到了破壞。而DDD正是維護(hù)軟件概念完整性的良藥。如果在項(xiàng)目中實(shí)踐 DDD 的成本不高,那么即使是小項(xiàng)目,從一開始就使用 DDD 不是一件很美好的事情嗎? 在軟件開發(fā)項(xiàng)目中實(shí)踐 DDD 到底有何難處?16 年了,難道在 DDD 實(shí)踐中碰到的問題我們不能從書本中尋得答案? 目前國內(nèi)已經(jīng)出版的DDD相關(guān)圖書中,除了 Eric Evans 的經(jīng)典著作之外,還有《實(shí)現(xiàn)領(lǐng)域驅(qū)動設(shè)計》《領(lǐng)域驅(qū)動設(shè)計精粹》《領(lǐng)域驅(qū)動設(shè)計模式、原理與實(shí)踐》等,不過寥寥數(shù)本。這與 DDD 的巨大聲望很不匹配,這也許說明了一些問題。 實(shí)踐DDD首先需要面對的一個(也許是最大的)難題是:難以描述的領(lǐng)域模型。 DDD 想要構(gòu)建的領(lǐng)域模型是什么?按照 Eric Evans 的觀點(diǎn),領(lǐng)域模型不是一幅具體的圖,而是那幅圖想要傳達(dá)的思想;不是一個領(lǐng)域?qū)<翌^腦中的知識,而是那些經(jīng)過嚴(yán)格組織并進(jìn)行選擇性抽象的知識。 聽起來是不是有點(diǎn)玄奧?系統(tǒng)分析師、產(chǎn)品經(jīng)理到底要拿出什么樣的領(lǐng)域模型才能說 “我的工作已經(jīng)做到位了”?這個模型到底是不是可以實(shí)現(xiàn)的?開發(fā)人員、測試人員到底有沒有理解這個模型?大家的理解是不是一致的? 說到底,一個領(lǐng)域模型要想有用,它必須足夠嚴(yán)格。如何使用一種嚴(yán)格的方式描述經(jīng)過嚴(yán)格組織并進(jìn)行選擇性抽象的知識呢? 問題的答案很自然地指向了 DSL。 其實(shí),Eric Evans 早就意識到了這一點(diǎn)。他曾經(jīng)在訪談中說: 更多前沿的話題發(fā)生在領(lǐng)域?qū)S谜Z言(DSL)領(lǐng)域,我一直深信 DSL 會是領(lǐng)域驅(qū)動設(shè)計發(fā)展的下一大步,F(xiàn)在,還沒有一個工具可以真正給我們想要的東西。但是人們在這一領(lǐng)域比過去做了更多的實(shí)驗(yàn),這使我對未來充滿了希望。 通過本書,我想要告訴大家的是:在項(xiàng)目中運(yùn)用 DDD 可以不像大家想象的那么痛苦,DDD 并不是只適用于大項(xiàng)目,使用 DDD 并不一定需要犧牲敏捷性,一切的關(guān)鍵在于 DSL 的運(yùn)用。 我和我工作過的團(tuán)隊(duì)曾經(jīng)在多個項(xiàng)目中使用 DSL 實(shí)現(xiàn)了 DDD 的真正落地。獨(dú)樂樂不如眾樂樂!現(xiàn)在,我想把這些實(shí)踐經(jīng)驗(yàn)分享給大家。 【讀者對象】 領(lǐng)域模型是一種“思想”,它可以為軟件開發(fā)的全過程提供指導(dǎo),所以我相信本書可以為很多人提供幫助: 產(chǎn)品經(jīng)理與系統(tǒng)分析師。產(chǎn)品經(jīng)理不僅僅需要保證團(tuán)隊(duì)開發(fā)的是“正確的軟件”,也不應(yīng)該只是關(guān)注軟件的界面原型、用戶體驗(yàn),更應(yīng)該讓軟件有內(nèi)涵。迷人的產(chǎn)品不僅需要漂亮的界面和交互,更需要邏輯自洽,功能處處傳達(dá)出一個思想——優(yōu)美而深刻的領(lǐng)域模型。在有的團(tuán)隊(duì)中,產(chǎn)品經(jīng)理同時也是系統(tǒng)分析師。作為近十幾年來最有影響力的軟件分析和設(shè)計的方法論,系統(tǒng)分析師有必要了解DDD,從中汲取營養(yǎng)。 架構(gòu)師。架構(gòu)師需要根據(jù)業(yè)務(wù)需求提供技術(shù)解決方案。DDD 想要構(gòu)建的領(lǐng)域模型不僅僅是領(lǐng)域業(yè)務(wù)知識的提煉總結(jié),也包含了對軟件設(shè)計的考量,可以用于直接指導(dǎo)軟件的編碼實(shí)現(xiàn)。構(gòu)建這樣的模型,需要架構(gòu)師的積極參與。 開發(fā)工程師。開發(fā)工程師應(yīng)該理解領(lǐng)域模型,領(lǐng)域模型應(yīng)該被忠實(shí)地映射到代碼實(shí)現(xiàn)中。代碼中對象的命名、對象之間的關(guān)系,都應(yīng)該與領(lǐng)域模型一致。唯有如此,代碼才能具備良好的可讀性、可維護(hù)性,敏捷 XP 方法的狂熱愛好者們所言的“代碼即文檔”才可能實(shí)現(xiàn)。 測試工程師。如今很多測試工程師已經(jīng)被稱為“測試開發(fā)工程師”,他們也應(yīng)該理解領(lǐng)域模型。測試工程師應(yīng)該像產(chǎn)品經(jīng)理一樣了解軟件的設(shè)計,甚至應(yīng)該比產(chǎn)品經(jīng)理更深刻地理解領(lǐng)域模型面向軟件設(shè)計所做的考量。實(shí)例化需求的自動化測試(或者說行為驅(qū)動測試)應(yīng)該基于領(lǐng)域模型,而非基于 UI/UE 來構(gòu)建,因?yàn)橛脩艚缑嬉约坝脩艚换ナ且鬃兊,而領(lǐng)域模型相對來說穩(wěn)定得多。 項(xiàng)目經(jīng)理。項(xiàng)目經(jīng)理是負(fù)責(zé)“正確開發(fā)軟件”的人。如果不深刻理解領(lǐng)域,不知道如何抓住領(lǐng)域模型中的關(guān)鍵點(diǎn),會很難評估任務(wù)工作量的大小以及應(yīng)該在何處投入足夠的資源,甚至無法判斷項(xiàng)目的實(shí)際進(jìn)度。 高校研究生以及其他有志于從事 IT 行業(yè)的人。 【如何閱讀本書】 本書的第一部分會帶領(lǐng)讀者從戰(zhàn)術(shù)層面以及戰(zhàn)略層面重溫領(lǐng)域驅(qū)動設(shè)計的重要概念,然后進(jìn)一步闡述Eric Evans經(jīng)典著作中沒有顯式提出的或者被太多人忽略的但我認(rèn)為對 DDD 落地非常重要的若干概念,同時簡要介紹從 DDD 社區(qū)興起的一些軟件架構(gòu)模式。通過第一部分,讀者可以更完整、更深刻地掌握 DDD 的知識體系。 第二部分闡述如何設(shè)計一種DDD的DSL,包括這個DSL的規(guī)范(Specification)支持哪些特性、如何幫助團(tuán)隊(duì)描述領(lǐng)域模型的方方面面、這些特性的選擇基于何種考量等。 這種領(lǐng)域?qū)S谜Z言需要一個名字,我們總不能一直說“我設(shè)計的 DDD 的 DSL”吧,于是我給它起了一個名字:DDDML。我認(rèn)為這是一個很棒的名字。其實(shí)這種語言叫什么并不太重要,重要的是它可以用一種足夠嚴(yán)格的方式描述領(lǐng)域模型。我認(rèn)為目前它在簡單與復(fù)雜之間取得了不錯的平衡。當(dāng)然,其中還有不小改進(jìn)的空間。比如,我很樂意讓它支持更多像“賬務(wù)模式”這樣的分析模式。 第三部分介紹如何將“思想照進(jìn)實(shí)現(xiàn)”——通過使用工具將描述領(lǐng)域模型的 DSL 文檔變成可以運(yùn)行的軟件。這個過程涉及大量的技術(shù)工具(工具鏈)的設(shè)計與實(shí)現(xiàn)。只有將這些技術(shù)工具——比如從 DSL 自動生成應(yīng)用的源代碼的模板——實(shí)現(xiàn)出來,才能減輕開發(fā)人員實(shí)踐 DDD 的負(fù)擔(dān),進(jìn)而提升而不是降低軟件團(tuán)隊(duì)的生產(chǎn)效率。本部分會介紹這些技術(shù)工具設(shè)計與實(shí)現(xiàn)的細(xì)節(jié)。 我和我的同事把自制的 DDDML 工具鏈稱為 DDDML Tools。出于商業(yè)原因,我無法展示這些工具的源代碼,但是會詳盡地展示這些工具運(yùn)行的結(jié)果——主要是由工具生成的應(yīng)用的源代碼。這些源代碼可能經(jīng)過一些簡化,但是與我們在生產(chǎn)系統(tǒng)上運(yùn)行的代碼十分接近,完全可以說明問題。 讀完全書,你將發(fā)現(xiàn)其實(shí)我們已經(jīng)全無秘密。你會熟知 DDDML 的規(guī)范,見到工具運(yùn)行的結(jié)果,你幾乎可以馬上動手制造自己的 DDDML 工具。其實(shí)設(shè)計 DDDML 的規(guī)范才是整件事情(使用 DSL 實(shí)現(xiàn)領(lǐng)域驅(qū)動設(shè)計)中最難的部分,制作工具不是。雖然想要復(fù)刻我們已經(jīng)做過的所有工具確實(shí)需要相當(dāng)大的工作量,但也僅僅是工作量而已。 幸運(yùn)的是,你并不需要制造整條 DDDML 的工具鏈才可以享受使用 DSL 的樂趣。比如,你可以先寫一些模板,生成一些持久對象(Persistant Object),它們無非是一些簡單的 Java 對象(Plain Ordinary Java Object,POJO),然后再生成一些 O/R Mapping XML,就可以馬上使用 JPA/Hibernate 來實(shí)現(xiàn)應(yīng)用的 DAL(數(shù)據(jù)訪問層)了。如果你再生成 Repository,那就更漂亮啦! 第四部分講述的是一些建模案例以及其他與 DDD 相關(guān)的話題。領(lǐng)域模型是一種思想,DSL 是一種工具,但是如何運(yùn)用、結(jié)果如何,因人而異。我希望通過輕松的漫談和隨想,將我的一點(diǎn)DDD應(yīng)用經(jīng)驗(yàn)分享給大家。 楊捷鋒, 曾就職于南開戈德集團(tuán)、普天集團(tuán)、通路快建等公司。曾作為獨(dú)立技術(shù)顧問為海爾集團(tuán)、沈陽飛機(jī)工業(yè)集團(tuán)、上廣電NEC、天馬微電子等企業(yè)提供軟件開發(fā)與技術(shù)咨詢服務(wù)。目前在一家電商創(chuàng)業(yè)公司擔(dān)任技術(shù)負(fù)責(zé)人。有多個大型企業(yè)應(yīng)用軟件的分析建模經(jīng)驗(yàn),以及大型開發(fā)框架(ORM、IoC等)的架構(gòu)經(jīng)驗(yàn)。多年來一直未脫離軟件開發(fā)一線工作,對軟件系統(tǒng)分析、數(shù)據(jù)建模、領(lǐng)域驅(qū)動設(shè)計、項(xiàng)目管理略有心得。 【第一部分 概念】 第1章 DDD 的關(guān)鍵概念 2 1.1 自頂而下、逐步求精 3 1.1.1 DDD開創(chuàng)全新分析流派 3 1.1.2 什么是軟件的核心復(fù)雜性 4 1.2 什么是領(lǐng)域模型 4 1.3 戰(zhàn)術(shù)層面的關(guān)鍵概念 6 1.3.1 實(shí)體 6 1.3.2 值對象 6 1.3.3 聚合與聚合根、聚合內(nèi)部實(shí)體 7 1.3.4 聚合的整體與局部 9 1.3.5 聚合是數(shù)據(jù)修改的單元 9 1.3.6 聚合分析是“拆分”的基礎(chǔ) 10 1.3.7 服務(wù) 12 1.4 戰(zhàn)略層面的關(guān)鍵概念 13 1.4.1 限界上下文 13 1.4.2 限界上下文與微服務(wù) 14 1.4.3 防腐層 15 1.4.4 統(tǒng)一語言 18 1.5 ER 模型、OO模型和關(guān)系模型 19 1.6 概念建模與模型范式 21 第2章 其他DDD相關(guān)概念 22 2.1 領(lǐng)域 ID 22 2.1.1 自然鍵與代理鍵 23 2.1.2 DDD 實(shí)體的 ID 需要被最終用戶看到 23 2.1.3 什么時候使用代理鍵 24 2.2 ID、Local ID 與 Global ID 26 2.3 命令、事件與狀態(tài) 27 第3章 CQRS 與 Event Sourcing 29 3.1 命令查詢職責(zé)分離 29 3.2 事件溯源 32 3.3 From-Thru 模式 33 3.3.1 示例:ProductPrice 33 3.3.2 示例:PartyRelationship 35 3.4 CQRS、ES 與流處理 36 【第二部分 設(shè)計】 第4章 DDD 的 DSL是什么 40 4.1 為什么 DDD 需要 DSL 41 4.1.1 為什么實(shí)現(xiàn) DDD 那么難 41 4.1.2 搞定 DDD 的“錘子”在哪里 42 4.2 需要什么樣的 DSL 43 4.2.1 在“信仰”上保持中立 44 4.2.2 DDD 原生 45 4.2.3 在復(fù)雜和簡單中平衡 46 4.2.4 通過 DSL 重塑軟件開發(fā)過程 48 4.3 DDDML——DDD 的 DSL 48 4.3.1 DDDML 的詞匯表 49 4.3.2 DDDML 的 Schema 51 4.4 DDDML 示例:Car 52 4.4.1 “對象”的名稱在哪里 55 4.4.2 使用兩種命名風(fēng)格:camelCase 與 PascalCase 55 4.4.3 為何引入關(guān)鍵字 itemType 56 第5章 限界上下文 57 5.1 DDDML 文檔的根結(jié)點(diǎn)下有什么 57 5.2 限界上下文的配置 59 5.3 名稱空間 62 5.3.1 再談 PascalCase 命名風(fēng)格 62 5.3.2 注意兩個字母的首字母縮寫詞 63 5.4 關(guān)于模塊 64 第6章 值對象 67 6.1 領(lǐng)域基礎(chǔ)類型 68 6.1.1 例子:從 OFBiz 借鑒過來的類型系統(tǒng) 70 6.1.2 例子:任務(wù)的觸發(fā)器 73 6.2 數(shù)據(jù)值對象 75 6.3 枚舉對象 76 第7章 聚合與實(shí)體 79 7.1 用同一個結(jié)點(diǎn)描述聚合及聚合根 79 7.2 實(shí)體之間只有一種基本關(guān)系 82 7.3 關(guān)于實(shí)體的 ID 85 7.4 不變的實(shí)體 89 7.5 動態(tài)對象 90 7.6 繼承與多態(tài) 92 7.6.1 使用關(guān)鍵字 inheritedFrom 94 7.6.2 超對象 95 7.7 引用 97 7.7.1 定義實(shí)體的引用 97 7.7.2 屬性的類型與引用類型 101 7.8 基本屬性與派生屬性 102 7.8.1 類型為實(shí)體集合的派生屬性 103 7.8.2 類型為值對象的派生屬性 106 7.9 約束 107 7.9.1 在實(shí)體層面的約束 107 7.9.2 在屬性層面的約束 109 7.10 提供擴(kuò)展點(diǎn) 110 第8章 超越數(shù)據(jù)模型 112 8.1 實(shí)體的方法 112 8.1.1 聚合根的方法 115 8.1.2 非聚合根實(shí)體的方法 116 8.1.3 屬性的命令 117 8.1.4 命令 ID 與請求者 ID 119 8.2 記錄業(yè)務(wù)邏輯 119 8.2.1 關(guān)于 accountingQuantityTypes 120 8.2.2 關(guān)于 derivationLogic 120 8.2.3 關(guān)于 filter 121 8.2.4 使用關(guān)鍵字referenceFilter 121 8.2.5 業(yè)務(wù)邏輯代碼中的變量 122 8.2.6 說說區(qū)塊鏈 123 8.3 領(lǐng)域服務(wù) 123 8.4 在方法定義中使用關(guān)鍵字 inheritedFrom 125 8.5 方法的安全性 126 第9章 模式 128 9.1 賬務(wù)模式 128 9.2 狀態(tài)機(jī)模式 132 9.3 樹結(jié)構(gòu)模式 137 9.3.1 簡單的樹 137 9.3.2 使用關(guān)鍵字structureType 138 9.3.3 使用關(guān)鍵字structureTypeFilter 139 【第三部分 實(shí)踐】 第10章 處理限界上下文與值對象 142 10.1 項(xiàng)目文件 143 10.2 處理值對象 144 10.2.1 一個需要處理的數(shù)據(jù)值對象示例 145 10.2.2 使用 Hibernate 存儲數(shù)據(jù)值對象 146 10.2.3 處理值對象的集合 149 10.2.4 在 URL 中使用數(shù)據(jù)值對象 151 10.2.5 處理領(lǐng)域基礎(chǔ)類型 153 第11章 處理聚合與實(shí)體 161 11.1 生成聚合的代碼 162 11.1.1 接口 163 11.1.2 代碼中的命名問題 178 11.1.3 接口的實(shí)現(xiàn) 179 11.1.4 事件存儲與持久化 207 11.1.5 使用 Validation 框架 218 11.1.6 保證靜態(tài)方法與模型同步更新 220 11.1.7 不使用事件溯源 222 11.2 Override 聚合對象的方法 223 11.3 處理繼承 225 11.3.1 TPCH 226 11.3.2 TPCC 227 11.3.3 TPS 228 11.4 處理模式 229 11.4.1 處理賬務(wù)模式 229 11.4.2 處理狀態(tài)機(jī)模式 234 第12章 處理領(lǐng)域服務(wù) 238 12.1 處理數(shù)據(jù)的一致性 239 12.1.1 使用數(shù)據(jù)庫事務(wù)實(shí)現(xiàn)一致性 240 12.1.2 使用 Saga 實(shí)現(xiàn)最終一致性 241 12.2 發(fā)布與處理領(lǐng)域事件 243 12.2.1 編寫 DDDML 文檔 243 12.2.2 生成的事件發(fā)布代碼 245 12.2.3 編寫生產(chǎn)端聚合的業(yè)務(wù)邏輯 253 12.2.4 實(shí)現(xiàn)消費(fèi)端領(lǐng)域事件的處理 254 12.3 支持基于編制的 Saga 255 12.3.1 編寫 DDDML 文檔 255 12.3.2 生成的 Saga 命令處理代碼 261 12.3.3 需要我們編寫的 Saga 代碼 268 12.3.4 需要我們實(shí)現(xiàn)的實(shí)體方法 273 第13章 RESTful API 276 13.1 RESTful API 的最佳實(shí)踐 276 13.1.1 沒有必要絞盡腦汁地尋找名詞 277 13.1.2 盡可能使用 HTTP作為封包 277 13.1.3 異常處理 279 13.2 聚合的 RESTful API 280 13.2.1 GET 280 13.2.2 PUT 291 13.2.3 PATCH 293 13.2.4 DELETE 295 13.2.5 POST 295 13.2.6 事件溯源 API 296 13.2.7 樹的查詢接口 297 13.3 服務(wù)的 RESTful API 297 13.4 身份與訪問管理 299 13.4.1 獲取 OAuth 2.0 Bearer Token 299 13.4.2 在資源服務(wù)器上處理授權(quán) 301 13.5 生成 Client SDK 302 13.5.1 創(chuàng)建聚合實(shí)例 303 13.5.2 更新聚合實(shí)例 304 13.5.3 使用 Retrofit2 306 第14章 直達(dá) UI 308 14.1 兩條路線的斗爭 309 14.1.1 前端“知道”領(lǐng)域模型 309 14.1.2 前端“只知道”RESTful API 312 14.2 生成 Admin UI 312 14.2.1 使用 referenceFilter 313 14.2.2 展示派生的實(shí)體集合屬性 315 14.2.3 使用屬性層面的約束 316 14.2.4 使用 UI 層元數(shù)據(jù) 317 14.2.5 構(gòu)建更實(shí)時的應(yīng)用 318 【第四部分 建模漫談與 DDD 隨想】 第15章 找回敏捷的軟件設(shè)計 322 15.1 重構(gòu)不是萬能靈藥 323 15.2 數(shù)據(jù)建模示例:訂單的裝運(yùn)與支付 324 15.2.1 訂單與訂單行項(xiàng) 325 15.2.2 訂單與訂單裝運(yùn)組 327 15.2.3 訂單與裝運(yùn)單 328 15.2.4 訂單的項(xiàng)目發(fā)貨 329 15.2.5 訂單的支付 330 15.3 中臺是一個輪回 332 15.4 實(shí)例化需求與行為驅(qū)動測試 334 15.4.1 什么是實(shí)例化需求 334 15.4.2 BDD 工具 335 15.4.3 BDD 工具應(yīng)與 DDD 相得益彰 336 15.4.4 不要在驗(yàn)收測試中使用固件數(shù)據(jù) 336 15.4.5 制造“制造數(shù)據(jù)”的工具 337 15.5 要領(lǐng)域模型驅(qū)動,不要 UI 驅(qū)動 345 15.6 不要用“我”的視角設(shè)計核心模型 346 15.6.1 讓 User 消失 347 15.6.2 認(rèn)識一下 Party 348 15.7 我們想要的敏捷設(shè)計 350 第16章 說說 SaaS 351 16.1 何為 SaaS 351 16.2 多租戶技術(shù) 352 16.3 構(gòu)建成功的 SaaS 有何難 353 16.3.1 多租戶系統(tǒng)的構(gòu)建成本 353 16.3.2 難以滿足的定制化需求 353 16.3.3 負(fù)重前行的傳統(tǒng)軟件公司 355 16.4 SaaS 需要 DDD 355 第17章 更好的“錘子” 356 17.1 我們制作的一個 DDDML GUI 工具 357 17.1.1 給領(lǐng)域建模提供起點(diǎn) 357 17.1.2 創(chuàng)建新的限界上下文 358 17.1.3 從 OFBiz 中“借鑒”數(shù)據(jù)模型 359 17.1.4 構(gòu)建項(xiàng)目并運(yùn)行應(yīng)用 361 17.1.5 使用 HTTP PUT 方法創(chuàng)建實(shí)體 362 17.1.6 給聚合增加方法 363 17.1.7 生成限界上下文的Demo Admin UI 368 17.1.8 讓不同層級的開發(fā)人員各盡其能 369 17.2 以統(tǒng)一語言建模 370 附錄 DDDML 示例與縮寫表 373
你還可能感興趣
我要評論
|