領域驅動設計(DDD)在百度愛番番的實踐

2021-03-06 架構頭條

本文以 DDD 為主題,詳細介紹了百度愛番番在過去一年多對 DDD 的探索、推廣和全面落地實踐,希望能對讀者有所啟發。

領域驅動設計(Domain Driven Design - DDD)起源於 2004 年 Eric Evans 出版《領域驅動設計》,相比於在國外 IT 圈享有盛譽且行之有效不同,國內 IT 圈了解 DDD 的人很少,落地實踐的少之又少。

最近幾年,隨著微服務架構的普及和中臺的興起,DDD 也成了各大技術論壇和微信公眾號文章裡經常談起的話題。DDD 的熱度是起來了,但業界介紹 DDD 的資料大多偏理論,缺乏生產項目可借鑑的實踐經驗。因此,大多人讀了很多 DDD 材料後還是一臉懵,怎麼衡量 DDD 帶來的價值?老闆能同意搞 DDD 嗎?什麼樣的業務和團隊適合 DDD?DDD 跟網際網路強調的小步快跑快速迭代能搭嗎?如果要實踐 DDD 產研團隊都要做些啥?研發寫代碼跟平時有什麼不一樣?

本文結合百度愛番番產研團隊在過去一年多經歷的從探索、推廣到全面落地 DDD 的過程,嘗試回答上述問題,力求給大家帶來一些借鑑意義。

百度愛番番圍繞營銷拓客和銷售提效幫助企業收集、擴充、清洗、培養、跟進和轉化線索。一方面愛番番的業務特點是典型的企業級(ToB)業務,具有一定的複雜度:業務對象多,單個業務對象提供的功能多,單個功能面向的場景多,業務對象之間組合出來的業務流程多。並且會隨著交付的功能越多而變的越複雜。另一方面產品處於爬坡階段,功能需要快速迭代交付到客戶,從而快速獲得客戶的反饋。產研團隊在資源一定的情況下如何高效交付更複雜的需求成為了主要矛盾。

分析當前階段需求迭代過程中的問題,可以總結為以下幾類問題:

業務邏輯不能從產品團隊精準傳遞到研發團隊,有時研發進行了一段時間開發才發現需求理解有偏差,導致需要重新跟產品經理討論需求。

產品團隊和研發團隊對於業務複雜度沒有的認識不統一,產品經理認為一個需求的開發不難,理應在較少時間內開發完畢。

研發團隊面對需求增長和變化時,缺乏對業務邏輯的抽象,往往開發一個需要點需要改動多處,容易出錯且開發效率低,代碼維護性差。

需求文檔和代碼邏輯不匹配,線上功能的業務邏輯為什麼實現成那樣沒有依據可查,領域知識得不到沉澱,團隊得不到可持續成長。

上述問題集中體現在兩個方面,一是產品屬於企業應用類,功能本身複雜,如何讓產研團隊快速理解業務,快速交付。二是如何讓領域知識能夠比較準確的得到開發實現,讓代碼有比較好的可維護性。借鑑業內處理複雜企業級軟體的開發經驗,加上部分團隊成員曾經有過 DDD 使用的經驗,團隊決定嘗試運用 DDD 設計思想來指導產研團隊的日常需求迭代。

DDD 是一種圍繞領域建模來解決複雜業務交付的設計思想。讀者不妨自問幾個問題,什麼是複雜?什麼是領域建模?

什麼是複雜?如何理解複雜?複雜可能是現狀業務就複雜,也可能是業務日漸演變成複雜。複雜來自規模在變,比如幾個業務對象的邏輯不複雜,幾十上百個業務對象就會變得錯綜複雜。複雜來自結構化不足,比如下圖所示,結構化的中國結比非結構化的義大利麵更有序、易於大腦理解。此外,一旦協同方多了,如何協同不同團隊完成軟體交付也是一種複雜。


什麼是領域建模?領域模型跟技術毫無關係,而是為了更有結構化的拆解和表達業務邏輯。業務邏輯來自現實世界裡的具體場景,涉及可視畫面、操作動作和流程。要準確表達業務邏輯需要先講清楚每個概念是什麼,再建立概念之間的聯繫,基於這些關係再組合出更多的流程。概念、聯繫、流程就是領域模型。圍繞領域模型去表達業務時也自然而然地把技術實現細節分離出去了。後續代碼實現就是將業務架構映射到系統架構的過程,以後業務架構調整了能快速的調整技術架構。

DDD 中的領域如何理解?

DDD 中表示業務邏輯的領域概念是:實體、值對象、領域服務、領域事件。這意味著所有領域邏輯都應該在這四種對象裡,統一稱為領域模型對象,這將極大減少業務邏輯的蔓延。

引入聚合進一步封裝實體和值對象,讓領域邏輯更內聚,起到邊界保護的作用。聚合的引入使得業務對象間的關聯變少。如何設計聚合見下面實踐部分。

圍繞聚合的操作引入工廠和資源庫。工廠負責複雜聚合的創建,資源庫負責聚合的加載、添加、修改、刪除。聚合內的實體狀態變更通過領域事件來推動。

引入應用服務,對領域邏輯編排、封裝。供上層接口層調用。一個應用服務就是一次編排,一次編排就是一個用戶用例。

DDD 領域概念詳細解釋和舉例


DDD 包含戰略設計、戰術設計、技術實現三個部分。戰略設計側重於高層次、宏觀上去劃分限界上下文,而戰術設計則關注使用建模工具來細化上下文,通過領域模型來表達業務。技術實現主要通過分層架構來隔離領域模型代表的業務邏輯和技術細節。

一個整體過程大致包括:宏觀劃分各領域 → 領域內劃分限界上下文,定義上下文之間的關係 → 上下文內分析業務,識別領域概念,定義合適的領域概念 → 通過分層架構實現編碼,並驗證領域模型的合理性,必要時重新回到前面步驟重構領域模型。

戰略設計

a. 戰略設計是團隊領導層或業務負責人關心的,該步驟需要針對產品願景、業務要解決的問題域,規劃核心域、通用域、支撐域,做合適的資源投入。

b. 什麼是領域和限界上下文?領域代表現實世界的特定問題和解決方案的集合,比如銷售領域、營銷領域。DDD 裡的限界上下文(Bouded Context)是對領域的軟體實現,比如線索系統、商機系統就是銷售領域內的限界上下文。限界上下文定義了解決方案的明顯邊界,邊界裡的每一個領域概念,包括領域概念內的屬性和行為都有特殊含義。出了限界上下文這個邊界這層含義就不復存在。

c. 如何劃分限界上下文?

根據相關性做歸類。一般是優先考慮功能相關性而不是語義相關性,比如創建訂單和支付訂單都是訂單語義,但功能相差比較大,應該劃分為兩個限界上下文。

根據團隊粒度做裁剪、根據技術特點做裁剪。一些通用的技術功能應該儘可能歸攏到一個限界上下文,比如每個業務限界上下文都有監控,但監控能力應該歸攏到監控限界上下文。

BC 與微服務什麼關係?微服務是包含高度相關功能的一個開發部署單元,有自己的技術自治性包括技術選型、彈性擴縮容、發布上線頻率等,有自己的業務演變自治性。BC 是根據領域邏輯的內聚情況形成的一個整體。一個微服務可以包含一個或多個 BC,到底包含幾個?需要根據團隊大小、BC 複雜度和技術特性來定。

戰術設計

DDD 設計思想裡領域建模是最核心的一步,該階段主要目標是提煉和定義出領域模型和之間的關係。

a. 領域建模:建模就是設計的過程,建模的過程就是梳理、走查業務邏輯,拆解為要解決的問題和涉及的業務場景、業務流程、業務概念,在這個過程中形成對應的領域概念。如果團隊對於業務比較陌生適合採用事件風暴方法進行梳理。如果團隊對業務比較熟悉,如果業務流程相對簡單,則可以採用四色建模法進行業務梳理。採用這些分析業務的方法可以保證產研團隊對業務邏輯的理解在一個水平上。

b. 業務邏輯的顯性表達:在完成了實體和值對象的設計後,有的時候會發現有些概念其實在領域上是存在的,但設計和代碼裡沒有 Class 來體現,可能僅僅是一個基本類型參數加上散落的對該參數的判斷檢驗邏輯,這個時候還需要思考應該把這個概念顯性化,定義專門的 Class 並包含相應邏輯,入出參以相應 Class 為類型。但凡業務代碼邏輯包含了一堆 if-else,這時候需要考慮儘可能給這段邏輯建模成一個領域概念。比如 CRM 系統裡判斷一條線索是否為推廣線索需要看線索的渠道屬性是否來自推廣平臺,那麼比較好的方式是這段邏輯用"推廣線索"這個概念來顯性表達,而不是淹沒在代碼裡不容易理解和維護。

c. 統一語言:為了解決業務邏輯銜接的問題引入了統一語言。每個業務名詞的含義具有明確的定義,產品和研發都統一認識。沒有統一語言的溝通嚴重缺乏效率。比如 CRM 線索的概念,沒有統一語言的時候每個人的理解不一樣,有的人理解為有過諮詢記錄的訪客是線索,有的人理解為留下過聯繫方式的訪客是線索,有的人理解為有購買意願的訪客是線索等等。有了統一語言描述,每個概念就有了明確定義,可以節省非常大的溝通交流成本。並且這個概念也同樣應用在相關的需求文檔、設計文檔、代碼編寫中。每個概念從引入到日常交流,從需求文檔到代碼實現都有了一致的表達,代碼實現和需求描述的真實度高,可理解性和可維護性就變好了。

技術實現

a. 分層架構:為了讓代碼實現圍繞領域模型開展,儘量降低業務代碼和純技術選型代碼的耦合,DDD 引入了分層架構。確保了最核心的領域層不依賴其他層,反過來讓領域之外的代碼依賴領域代碼,降低了技術升級帶來的影響。

b. DDD 框架:框架內定義不同領域概念需要實現的接口,比如實現了聚合根接口的實體類就成為了聚合的根實體。定義了異常管理規範,不同的分層應該拋出什麼類型的異常。定義了數據訪問的資源庫接口等等。

c. 領域事件:領域事件是對領域內發生的活動進行的建模,即聚合內的實體狀態變化的一個載體。DDD 提倡限界上下文間儘量解耦,儘可能使用發布訂閱領域事件的協作模式進行上下遊解耦。

傳統的業務開發模式裡,研發受到關係型資料庫設計範式、ER 圖等影響深遠,在做軟體詳細設計過程中往往先想到如何設計對應的表結構,由此倒推出業務邏輯代碼該如何組織。這就是典型的數據模型驅動設計,或者叫面向數據表設計編程。數據模型設計關注的是數據存儲,數據儘量不要冗餘,控制表數量不膨脹。更多考慮數據的擴展性,比如新加一個欄位儘量不要在幾張表都加,能用一個欄位表達就不用兩個欄位。這樣的思維跟 DDD 是相反的,DDD 優先考慮領域概念的業務語義表達,具有獨立業務概念的東西會儘量抽象成一個內聚的領域對象。領域對象不僅僅有屬性,還有該有的行為。因此基於數據模型驅動的設計結果往往是:

業務邏輯代碼非常過程式,領域實體只包含一堆屬性,只是數據表的映射,沒有業務行為。也就是常說的只有 getter 和 setter 方法的貧血對象。非常缺乏領域概念的表達,業務邏輯散亂。比如值對象的設計在 DDD 裡是一個類,在數據模型設計裡往往是其他類的幾個屬性。

聚合是 DDD 最小的復用單元,粒度更粗。數據模型設計裡領域實體的數量跟表數量一一對應,數據表是最小的復用單元,粒度太細。導致業務邏輯對應的實現類需要訪問很多的領域實體,實現類之間的調用關係發散而錯綜複雜。下圖是貧血模型和 DDD 富血模型的區別。

當然,DDD 思想裡不是說不用考慮數據表設計,而是要優先考慮領域概念的識別和建模。表設計需要服務於領域模型的設計,是技術實現的細節。因此明白 DDD 和數據模型驅動設計的區別反過來能更好地理解 DDD。

以愛番番業務中"線索"功能舉例,線索管理功能特別多,有創建、清洗、分配、打標籤、跟進、回收、退回和轉化等十幾個管理動作。僅線索創建就分為手工錄入創建、文件導入創建、營銷系統的後臺自動創建、開放平臺創建,創建還分為單個創建和批量創建等等。線索這個對象跟其他對象比如客戶、商機等聯動組合出來很多場景和流程。

規劃階段需要考慮產品願景和服務藍圖,需要劃分出產品的核心領域,支撐領域,通用領域。如果從 0 到 1 開發產品的話規劃階段需要做很多的工作,比如開發一個 CRM 產品需要考慮產品願景和服務藍圖,需要聚焦到哪些業務領域,是售前、售中還是售後?售前還可以細分為營銷領域還是銷售領域等等。百度愛番番致力打造易用的、靈活可配的線索管家功能。因此銷售領域的線索功能自然是核心模塊。需要提供什麼線索功能?需要通過分析階段來拆解。

分析階段是基於業務流程和功能分析出具體的業務對象,不同的業務對象歸屬劃分到限界上下文。因為線索功能複雜,團隊對於線索功能認知不一,有必要讓相關人員一起採用事件風暴方法來分析和梳理業務。事件風暴認為事件流很⼤程度上反映了現實業務邏輯,參與人員基於領域事件發生的時間線,把事件的前因後果逐步挖掘出來。整個過程包含識別領域事件、決策命令、領域名詞三個步驟。通過嘗試回答這幾個問題:這個業務涉及的系統產生了什麼變化?變化由哪個角色通過什麼方式觸發的?系統變化產生了哪些結果?

基於上述步驟,領域專家和相關人員針對線索業務進行事件風暴的結果為:


事件風暴關鍵圖例:


事件風暴實踐過程的幾點 tips:

事件流幾乎等同業務邏輯,以此來推敲業務邏輯的嚴密性,有果必有因。

緊扣事件要素:事件、規則、名詞、命令、角色。

命名:緊扣業務,不參雜技術元素,警惕使用泛泛的詞彙,儘可能地消除命名的⼆義性。

優先關注 happy-path 即正常路徑,聚焦核心領域裡的路徑。

事件風暴不是一蹴而就,保持迭代更新。

基於事件風暴的結果,需要把領域名詞和規則等劃分到合適的限界上下文。根據前面介紹的如何劃分限界上下文的方法,線索相關功能劃分為幾個限界上下文合適呢?這個時候需要看業務邏輯的複雜程度,還要結合團隊規模大小。由於線索功能包含很多業務邏輯,線索歸集和創建、線索的分配、線索的跟進等都可以成為一個獨立的限界上下文。定義好限界上下文後還需要定義不同限界上下文的協作關係。一般情況下如果業務允許的情況儘量選擇通過領域事件來協作。根據《領域驅動設計》所述常見的協作關係還包括開放主機服務(即通過暴露接口)、共享內核、防腐層等 9 種。微服務架構下的限界上下文之間的關係比較常見的有領域事件、開放主機服務、防腐層等。

設計階段就是把分析階段產出的領域名詞,領域事件,決策命令用 DDD 領域概念來承接,並細化每個領域概念的數據和行為。這也是一種領域建模的過程。建議的建模過程是:

業務需求的分析過程自上而下,由業務流程,到用戶用例,到領域模型。而設計過程是自下而上的。從領域元素設計開始,最後才是應用服務的編排。

建議設計優先級是先值對象 → 再實體 → 再聚合 → 再領域服務→ 最後是應用服務,優先考慮領域是否應該為值對象,其次是否為實體,劃分出聚合。不屬於實體或值對象中的領域行為放到領域服務,需要協調聚合的領域行為設計為領域服務或者應用服務。

任何業務代碼邏輯優先映射到原子性的領域模型,比如值對象、實體、領域事件、資源庫接口、外部適配接口,其次再映射到組合性領域模型,比如領域服務、應用服務。

建模過程中經常會被問到的問題有:

值對象可以定義自己的行為嗎?

【答】可以,儘可能把屬於值對象自己的行為放到值對象裡。比如聯繫方式定義成一個值對象,如果它的校驗只依賴自身數據,那校驗行為應該屬於在聯繫方式這個值對象。

聚合該設計為多大粒度?

【答】聚合設計要儘量小,如果一個實體不是根實體,但同時需要被外界直接訪問到,那麼這個實體不應該在這個聚合中,應該獨立成新的聚合。

一個聚合如何訪問另外一個聚合?

【答】只有聚合根才是訪問聚合邊界的唯一入口,因此一個聚合需要通過另一個的聚合的聚合根來訪問它,聚合根可以理解為聚合的根實體的 Id。

應用服務與領域服務的區別?

【答】領域服務處在分層架構的領域層,是領域邏輯的一部分。應用服務處在應用層,負責領域模型的編排。當業務邏輯不屬於任何聚合時,應該考慮用領域服務來封裝這些邏輯。比如判定訂單是否重複,應該屬於訂單限界上下文的一種業務邏輯,訂單聚合本身不能判斷是否重複,因此訂單判重應該定義為領域服務。

應用服務可以直接調用聚合和資源庫嗎?

【答】可以,可被應用服務編排的對象包括聚合、資源庫、領域服務和適配接口。

領域事件內容是包含整個聚合裡的信息,還是身份標識信息 (訂閱方再通過單獨接口根據標識進行查詢),還是只包含聚合中一些特定的信息?

【答】領域事件是用於跟其他聚合協作,事件內容不應是整個聚合,而是經過裁剪的特定信息。

根據分析階段的產出結果,需要把領域名詞、規則映射到領域模型。主要幾個線索相關領域對象如下圖示:


傳統的接口 - 邏輯 - 數據訪問三層架構裡,業務邏輯層的 XxxServiceImpl 類是個上帝類,往往通過過程式業務邏輯實現。前幾行代碼做校驗,接下來做數據類型轉換,然後是業務處理邏輯的代碼,中間穿插著通過接口或者 dao 獲取更多的數據,拿到數據後,又是類型轉換代碼,然後接著一段業務邏輯代碼,最後可能還要落庫,發布消息等等。這樣的代碼參雜了太多不同的代碼,非常難以維護。

業界自從 DDD 的分層架構提出後陸續出現過洋蔥架構、六邊形架構、整潔架構等,其目標都是為了分離業務和技術,保證領域模型的純粹性。下圖是結合業界架構實踐後定製的分層架構,具有以下幾個特點:

接口層負責對外暴露各種協議的接口比如 http、tcp,轉換成應用服務能認識的協議。

核心的領域層不依賴其他層,通過資源庫包下的接口定義做到依賴倒置,接口參數不能體現具體技術實現細節,領域模型裡的實現邏輯只依賴接口。這樣做到對領域邏輯的一層防腐。本層裡以聚合為單位放置代碼,便於以後系統拆分,以聚合為單位。

應用層定義應用服務,一個接口對應業務場景的一個用例。此外應用層還可以處理橫切面事務比如啟動資料庫事務。

基礎設施層完成資源庫的實際實現,以及領域層定義的其他接口的實現如對外部服務的訪問,領域事件發布到消息隊列中間件等。

分層架構還定義了每層的項目包結構,不同的領域概念和數據對象相應的命名規範。


實現階段經常會被問到的問題有:

每層應該用什麼類型數據對象承載和傳遞數據?

【答】如上面分層架構圖所示,接口層和應用服務層用 DTO 對象傳遞數據,領域層只能見到領域對象即聚合、實體 Entity 和值對象 VO。應用服務層負責把 DTO 對象轉換成領域對象傳輸到領域層。基礎設施層用 PO 表示數據表,跟領域層調用時需要把 PO 和領域對象相互做轉換。

repository 和 dao 的區別?

【答】都能訪問數據,區別在於訪問粒度或邊界。repository 有邊界控制作用,比如不能直接操作值對象對應的表。dao 沒有邊界,想操作哪張表就哪張表。

領域事件的發布應該在領域層還是應用層?

【答】只要不會破壞各層的依賴順序,在哪發布都行。取決於領域事件定義在哪層?一般推薦定義在領域層的聚合內。當然即便在應用層發布事件也不會破壞依賴方向。因此聚合、領域服務、應用服務都可以發布事件。

以 java 代碼為例,DDD 骨架代碼包含了分層架構,每層就是一個 maven pom 項目,根據用途定義好了多層包結構,每個領域對象和數據傳輸對象都有具體的命名方式。基於自研的 ddd-framework 規範了不同領域對象需要實現的接口或繼承於特定的基類。總之儘可能做到了能根據需求文檔裡的業務邏輯很快找到代碼所在之處,讓不同的代碼待在應該待的分層和包下面。團隊成員開玩笑說,現在開發業務代碼就像在做填空題,簡單直白。


目前百度愛番番的新服務默認都會在符合 DDD 架構的骨架代碼基礎上開發,存量的核心模塊也進行過 DDD 改造。全面實施 DDD 後產研團隊目標更對齊,協作效率更高,收穫了很多收益,包括但不限於以下幾點:

產研團隊協同成本降低,領域知識得到積累和沉澱。統一語言的使用和維護極大提高了大家對齊的成本。

業務語義得到顯性表達,業務邏輯內聚可復用程度提高,避免了很多散彈式修改和發散式修改。一個需求不用改多個地方,多個需求也不用幾個研發集中改同一個地方。

限界上下文的劃分從業務合理性出發,進而微服務的劃分會更合理,減少了團隊間的耦合和不必要的協同代價。

接口數量精簡、可控。由於業務代碼聚焦領域模型,邏輯內聚,復用性高,急劇減少了接口數量,降低接口維護成本。

通過預定義好的腳手架創建符合 DDD 規範的代碼骨架,提高了新服務開發的效率。

代碼可讀性高,不是代碼作者也能快速定位到代碼位置,代碼設計能夠得到傳承,可維護性也提高了。

新人熟悉新業務和新代碼的速度極大提高,業務和技術知識的轉移代價減低。

從需求到交付的一次典型軟體開發流程包括收集提煉需求、需求分析、業務 & 技術設計、代碼實現、測試上線等環節。如何結合軟體開發流程,每個流程階段具體要做什麼,怎麼做,特別在編碼落地階段該有什麼保障措施?愛番番產研團隊在落地過程中逐步總結出了一套行之有效的 DDD 實施指南。包括規劃、分析、設計到實現四個階段對應的方法和產出等實施要點。

DDD 一方面使用分而治之的思想,引入劃分領域、限界上下文、模塊分層、劃分聚合在不同層次、不同粒度來降低問題的複雜度。另一方主張聚焦領域邏輯,通過不同手段來減少業務和技術的耦合。因此 DDD 只是大部分軟體設計思想一種,軟體設計的本質都是為了高內聚低耦合。但是 DDD 並不是萬能的,不是所有業務開發場景都適合用 DDD。有些簡單業務場景不使用 DDD 反而更恰當。因為 DDD 有較高的學習門檻,需要整個團隊形成統一認識和協同,需要相應的編碼規範和架構落地。因此學習和落地 DDD 時要時刻記住自己的出發點是為了應對現在或者將來的複雜業務領域而來。不必太拘泥於某些點是否遵守了 DDD 原則,如果覺得用了 DDD 會比沒有用好一點點,也值得邁出這一步。

愛番番產研團隊始終秉持「以客戶為中心」的理念,運用 DDD 設計思想構建統一的業務模型,實現業務功能的復用和融合。隨著愛番番業務的發展,我們相信 DDD 帶來的收益會更大。今後我們會從產品、技術、流程和組織方面持續關注能有效解決軟體工程複雜性問題的方法。

飛邪,在百度愛番番主要負責銷售域和連通域的技術,長期關注技術團隊如何高效服務產品團隊等研發效能話題,擅長 ToB 企業級應用的規劃和落地。

這可能是網上最全的Docker工具集合

點個在看少個 bug 👇

相關焦點

  • DDD臺灣年會演講-領域驅動設計參考過程模型
    ,涵蓋了領域驅動設計統一過程從全局分析、架構映射到領域建模的設計全貌。說明:演講過程中提到的「業務活動」,在最新版本的內容中,已經調整為「業務服務」,「場景驅動設計」也相應調整為「服務驅動設計」。領域驅動設計參考過程模型如下圖所示:詳細內容可以閱讀我的著作《解構領域驅動設計》,計劃在春節前後出版。
  • 人人都在跟風學微服務,卻不知道DDD領域驅動設計?
    微服務與DDD領域驅動設計模型什麼是DDD領域驅動設計最先介紹領域驅動設計(domain-driven design)的是在程式設計師 Eric Evans 2004年出版的《領域驅動設計:複雜軟體核心複雜應對之道》書籍中,領域驅動設計是領域概念的擴展和應用,並且將它應用在軟體開發中。
  • 領域驅動設計(DDD)理論啟示
    2004年著名建模專家Eric Evans發表了他最具影響力的書籍《Domain-Driven Design –Tackling Complexity in the Heart of Software》(領域驅動設計—軟體核心複雜性應對之道),書中反覆強調領域通用語言(Ubiquitous Language)的重要性,全面闡述了DDD戰略設計到戰術設計的方法論和實踐。
  • 一文揭秘領域驅動設計(DDD):領域和子域!
    -     前言     -眾所周知,領域驅動設計(DDD)是個相當抽象的概念,國內除了幾家知名大廠有成功實踐外,更多技術團隊還處於探索階段實現業務其實是在實現所在業務領域中所需要的業務。技術也是一個領域,稱之為技術領域。領域驅動設計中的領域是指的業務領域。大多數的技術人員對技術領域中的知識比較感興趣(狂熱),因為這能夠使得自己在技術方面有一些前沿性和探索性的實踐。然而對於業務領域中的知識就顯得比較暗淡一些。當項目的進展隨著對業務領域的深入,大家又開始為各種曾經沒有分析到的需求忙的焦頭爛額。
  • 領域驅動設計框架Axon實踐
    領域驅動設計,DDD)這一著作,並在書中對領域驅動作出了開創性的理論闡述,至今領域驅動設計已問世十幾年。愛奇藝號技術團隊,在實施微服務化過程中,應用領取驅動思想,採用Axon框架落地了多個服務,下面是實施過程中的經驗總結。愛奇藝號合同中臺面向用戶提供籤約功能,從發起籤約到運營審核、供應商、採購單、掃描件、歸檔等流程漫長,狀態頗多,業務較為複雜,同第三方系統交互較多,對於有問題數據需要進行定位和回溯。
  • 領域驅動設計的實踐 – CQRS & Event Sourcing
    命令查詢與職責分離(Command Query Responsibility Segregation)和事件溯源(Event Sourcing)是為一種領域驅動設計的實踐。本文旨在簡要介紹CQRS & Event Sourcing, 希望能夠給大家在設計業務系統上提供一種新的思路和選擇。在開始介紹CQRS之前,有必要先了解DDD中的一些基本思想和概念。
  • 推番!!!
    從去年開始就鴿鴿又鴿還是鴿的推番,今天,0499正式發送
  • 番!必!備!10個正版追番網站推薦!
    總所周知,身邊大多數喜歡二次元愛追番的小夥伴,想要看到新番動畫,就繞不開
  • DDD分層架構最佳實踐
    而運用領域驅動設計(DDD)理念以應對日常加速的業務變化對架構的影響,架構的邊界越業越清晰,各施其職,這也符合微服務架構的設計思想。以領域驅動設計(DDD)為理念的分層架構已經成為微服務架構實踐的最佳實踐方法。一、什麼是DDD分層架構1. 傳統三層架構要了解DDD分層架構,首頁先了解傳統的三層架構。
  • DDD 領域驅動設計簡單介紹
    不同於其它的架構方法,領域驅動設計DDD(Domain Driven Design)提出了從業務設計到代碼實現一致性的要求,不再對分析模型和實現模型進行區分
  • 驅逐胡擄的大明帝國為何離不開番兵番將?
    這個始終自我標榜為拒外先鋒的帝國,往往在私底下最愛使用番兵番將。甚至發展為無法割捨的地步,堪稱古代世界的口嫌體直代表。  要理解明朝既定方針的自我矛盾性,就必須從朱元璋親手訂立的諸多政策講起。雖然之前的蒙古統治尚不足百年,卻因固有習慣而讓整個東土都毫無保留的敞開大門。
  • 代數學之父:丟番圖
    這位心碎的老人為了轉移自己的悲傷,開始整理大量的代數問題,並將這些問題及其解法彙編成書,取名《算術》(Arithmetica)。其中提到,他只活到了「父親歲數的一半」,但這是指兒子死時父親年齡的一半,還是指他父親壽命的一半?不論怎樣理解,都可以解答。但如果是後一種理解「只活到他父親壽命的一半」,我們得出的歲數會是一個漂亮而又簡潔的整數。我們假設丟番圖的壽命為x。
  • TGIF丨泡麵番試吃報告
    「民工漫」太長補不起來,純愛太無聊,工口不讓看,唯有泡麵番能在此時拯救你於水火之中。今天就來為大家鑑賞一下各種泡麵番的味道如何吧~先從吒吒我的最愛開始說起吧~《關於完全聽不懂老公在說什麼的事》,日常溫馨向的泡麵番,大概就是死宅娶了一個現充老婆的故事(怎麼可能!)
  • 那些深夜老司機們愛看的肉番!
    但是在日本,有一類動漫基本只能在深夜時段播出,這些動漫遊走在一些規則的邊緣地帶,一般被稱作是深夜番。聽這個名字的話我想很多人就大體能想到是什麼動漫了,基本就是賣肉、後宮類的一些動漫!今天我們就開開葷,推薦幾部可口的肉番吧,一言不合就飆車!
  • 追番!長假追番必備神器&附優質資源~
    文章看完記得順手點個【在看】,給搜羅君一點鼓勵,讓我持續給大家分享好軟體!軟體介紹及使用~軟體整體看起來也比較小清新的感覺,適合追番的小夥伴,有一種自由的氛圍~可以查看最新番劇的播放時間,求番。也可以按照分類尋找自己想看的番劇有哪些。
  • 口嫌體直:驅逐胡虜的明帝國為何離不開番兵番將?
    ▲來泉州做生意定居的阿拉伯商人 圖源於網絡所以,不但沿海的廣州、泉州出現了移民社區,連大運河沿線的江淮城市也充滿了異域情調。▲ 手中蒙古騎兵的優劣 決定了靖難之役的勝敗歸屬 圖源於網絡1399年,就藩北平的燕王朱棣突然起兵,掀起了同室操戈的靖難之役。大量來自朵顏三衛的蒙古土官,就帶著自己的人馬加入到叛軍一邊。
  • 如何運用領域驅動設計 - 領域事件
    概述在實踐領域驅動設計(DDD)的過程中,我們往往會遇到多個領域對象相互交互的情況。比如聚合根A在執行某操作之前需要得到聚合根B的某個信號(或某些數據)。如果在單體應用程式中,我們有條件和機會使得兩者進行強引用來完成操作,但是這將直接打破領域驅動設計的規範,從而使得項目不可控,再次回到大泥球的開發。
  • 分享幾款追番神器(安卓蘋果都有)能看b站大會員番
    追番神器「Nieta」,適用於安卓系統。軟體綠色無毒,頁面非常清新!安裝核心後,跳過彈窗即可使用!軟體的最大優點就是番劇賊多,包含全網!B*哩站大會員能看不能看的,這裡通通能看,而且畫質還非常高清,支持1080P,還有彈幕功能! 櫻花動漫是一款追番神器,裡面有大量的動漫汁源。無需會員即可播放,除了動漫還有豐富的歐美、日韓劇集。
  • 《陰陽師·平安物語》泡麵番又給陰陽師這個IP加入新的料
    從《陰陽師》官方漫畫到≪陰陽師≫~平安繪巻~音樂劇再到4月21日開始六播出的泡麵番《陰陽師·平安物語》,這種層層鋪設的IP運作,在國內的泛娛樂IP計劃中也是並不多見的。2018年4月21日,《陰陽師》泡麵番《陰陽師·平安物語》B站開播第一話:《達摩的一天》,時隔三天,播放量便達到128.6萬,追番人數72.2萬,彈幕4.6萬,評分9.7,《陰陽師》百度指數周六飆升到了3萬2,對於一部手遊衍生的國產泡麵番,這是一個非常優秀的成績了。▼ 開播首日,《陰陽師》的百度指數飆升到了3萬2
  • 【技術貼】如何有效的看到泡麵番
    某些人要的泡麵番合集!!!的文章我發現大家對於泡麵番資源還是很感興趣,大多數童鞋也加我獲取資源或者觀看方式,但是隨著淨網的力度越來越大,一些資源稍微敏感就不得分享出來,直接和諧在網盤中,即使能分享也是刪減版,那麼我們有什麼辦法可以解決現狀問題嗎?