一文搞懂DDD的12個核心概念與2大建模方法
本文詳細介紹了領域驅動設計(DDD)的十二個核心概念及兩大建模方法,旨在幫助讀者理解DDD設計理念,掌握其在實踐中的運用技巧,從而提升個人技術水平和業(yè)務理解能力。
一、前言
領域驅動設計簡稱“DDD”,一套“知易行難”的方法論。同時我所工作的這些年,尤其在某大廠做初創(chuàng)項目的那段時間,經常會產生各式各樣的“思想碰撞”,特別在設計中臺基建類領域時,為了保證充足的擴展性和穩(wěn)定性,都要好好的“碰撞”一下。雖然在設計過程中,每個人的想法不盡相同,但是最終達成一致的那一刻,每個人的技術思想都會得到提升。
對于DDD,我的觀點是,它是一套非常優(yōu)秀的能提升個人認知高度的方法論。注意,我說的是個人認知,不僅是它所帶來的業(yè)務和團隊價值(它所帶來的業(yè)務和團隊價值會在下面講)。它的戰(zhàn)略設計方法論能很好提升技術人員的全局視野,它的戰(zhàn)術設計方法論也能強化個人的技術細節(jié)把控力和結構性思維。除此之外,好的DDD設計也反映出一個技術人員對于業(yè)務的理解力,往往優(yōu)秀的領域專家也是半個業(yè)務專家。
如果你一直困惑于自己究竟該如何提升技術和業(yè)務思考能力;如何提升全局視野,提升自己的結構化思維的能力;如何在寫了這么多代碼,做了這么多需求的情況下,補充系統(tǒng)化的技術理念。如果這些疑惑點你都涉及,那么理解DDD,同時按照DDD的方式去思考和建設,能夠為你帶來顯著的提升。
同時我還要說明下,因為DDD的一些概念比較抽象,會讓剛了解的同學產生困惑和模糊感,所以關于戰(zhàn)略和戰(zhàn)術設計部分,我都會用實際的例子來解釋。基于我的經驗,最簡單的解釋才是有效的,所以我會用非常白話的方式表述清楚DDD的實戰(zhàn)部分,所以大家不用擔心理解問題。
PS:我最后想了下,還是要用個完整的示例來演示下DDD的建模流程,否則光說理論體感太弱,所以文章最后部分,我結合四色建模,加上我自己的過往建模經驗,演示了某體驗產品0-1建設的具體流程(暫不涉及代碼和工程部分),比較喜歡看具體示例的可以直接拖到最后一部分。
二、DDD是什么
2004年,Eric Evans在發(fā)表了一部名為《Domain Driven Design》的著作,其中提及了一套從系統(tǒng)分析到軟件設計的方法論——領域驅動設計,簡稱DDD,領域建模的思想隨即鋪展開來。
DDD設計的目標是實現軟件系統(tǒng)與業(yè)務需求的高度契合,提高開發(fā)效率和質量,同時也能更好地應對復雜性和變化性。它強調以業(yè)務為中心,通過深入領域知識和建立有效的領域模型,來驅動軟件設計和開發(fā)的整個過程。其中幾個核心理論提煉如下:
領域驅動設計——軟件設計復雜性解決之道。它是為了解決復雜軟件設計的一種優(yōu)秀方案,但不是唯一。
它把所有的業(yè)務規(guī)則、定義、范圍、知識等抽象成了一個大的概念,叫做領域。比如用戶支付的業(yè)務場景,叫做交易域;平臺提供售后等服務叫做服務域(或客服域),還有其他諸如金融域,人效域,物流域等。
它應對復雜性的思想,總結下來既簡單,又精煉,叫做“分而治之”。把最大化的領域(復雜問題)分為下層的一個個子域,同時每個子域又規(guī)定好邊界和核心實體,通過一系列的拆分、歸類、衍生,最終找到最優(yōu)解。
業(yè)務是在變的,如何從多變的業(yè)務環(huán)境中,保持內核的穩(wěn)定性和擴展性,適應多變的業(yè)務發(fā)展,這是應對復雜性的第二個關鍵點。領域模型是一套貫穿了整個軟件,從設計到交付的生命周期的方法論,因為他的共識性,可以讓開發(fā)、產品、架構師圍繞著統(tǒng)一的模型去設計和探討,不至于走樣。
領域模型的圖形表達方式,在實操上除了實體模型圖的表達比較特殊,其他的時序、狀態(tài)機、流程圖其實無特殊性。
領域模型是業(yè)務的抽象,這點很關鍵,同時領域模型的設計應該是基于現實,但不等于現實。
評論領域模型設計是否優(yōu)秀的方法很簡單:5年后,剔除掉所有的增值域,第一版建設的域模型是否還符合優(yōu)秀的穩(wěn)定性、擴展性和靈活性。
領域模型不是所有的軟件工程都適合,我經常會問面試者一個問題,一個FBI(數據看板系統(tǒng)),一個電商交易系統(tǒng),它們都適合用DDD嗎,為什么?
三、DDD和MVC的比較
在講解DDD的價值前,我們先看下DDD這個理念提出來之前,經典的MVC開發(fā)模式。
如圖,Controller負責業(yè)務邏輯的處理,Model代表和持久層交互的數據模型,View層負責視圖展示。MVC架構其實很精粹,清晰,對于業(yè)務邏輯并不復雜,單一化的場景其實效率是很高的。但是隨著業(yè)務的多變性和不斷復雜化,MVC架構就會暴露以下問題:
MVC架構沒有邊界劃分的概念和規(guī)范,在復雜的業(yè)務場景下會造成盤根交錯的邏輯依賴,同時隨著業(yè)務場景的不復雜化,代碼意圖會逐漸模糊,維護成本增加,對于系統(tǒng)的穩(wěn)定性也會帶來挑戰(zhàn)。
MVC僅反映軟件架構的分層,不定義業(yè)務語義的抽象和表達,對于業(yè)務知識的沉淀和復用性來說,不太友好。
MVC分割了數據和行為的表達,Model層(pojo)定義數據,Service層表述行為,會造成業(yè)務邏輯的首尾分離。
于是,為了解決以上問題,DDD的概念被提了出來。
四、DDD究竟能帶來什么價值
1. 業(yè)務(團隊)價值
(1)統(tǒng)一語言
同一團隊,同一語言。這里的團隊不僅是指技術團隊,也包含業(yè)務、運營、產品、質量等。所有角色的認知語言統(tǒng)一化,不論是在溝通、設計、文檔編寫、畫圖、編碼等任何環(huán)節(jié),都使用同一種語言,保證效率的最大化。
(2)清晰的邊界定義
DDD的非常重要的一個概念,就是劃分領域和子域的邊界,通過邊界和核心實體的聚合與建立,定義出清晰的業(yè)務范圍,避免邊界紛爭(技術人員應該經常會遇到,明明這個事情屬于A范圍,但是卻要B的應用改造;明明很基礎的一個通用能力,AB兩個應用各做了一個,改造成本*2,同時還要兜底解決一系列不一致問題)。
(3)領域能力沉淀和復用
業(yè)務能力的可復用性,是衡量軟件架構設計優(yōu)秀與否的一個重要指標,強大的復用能力,對于研發(fā)效能和業(yè)務效能的提升具有很好的正向作用。DDD通過領域能力的沉淀和打磨,使業(yè)務和模型統(tǒng)一,也使領域能力得以傳承。
(4)面向業(yè)務建模
基于現實業(yè)務做業(yè)務領域的抽象,切分數據和領域(業(yè)務)模型,從而降低整個軟件復雜度。開發(fā)人員應始終聚焦于領域模型,而不是傳統(tǒng)理念中關注數據層和接口層的設計。
(5)設計和代碼的等價
設計即代碼,代碼直觀表現設計。好的DDD設計,在方案上一句代碼都沒有,但是卻已經清晰的表明了所有的代碼實現(尤其在代碼結構、層次、定義上會感受得更清楚)。
2. 個人價值
(1)提升全局視野
做領域建模的第一階段是戰(zhàn)略設計,其實就是在做全局業(yè)務,流程的梳理,同時對于其中的域劃分都要有清晰的標準。要梳理清楚剛說的幾項內容,沒有全局的認知和思考是不行的,同時當負責人員梳理完這一階段的時候,潛移默化的其實就已經提升了個人的全局意識和視野了。這也就是我們常說的一個領域專家,也往往是半個業(yè)務專家的由來了。
(2)提升業(yè)務sense
這個和團隊價值中“面向業(yè)務建?!本邆鋸婈P聯(lián)性,因為DDD是面向業(yè)務建模為出發(fā)點,所以一切都需要在具備優(yōu)秀的業(yè)務敏感度下進行,沒有業(yè)務sense也做不好DDD,而做好了DDD,業(yè)務sense也一定不錯。同時在某大廠接觸DDD前期,讓我收益最大的一句話是——“業(yè)務不吃透,不聊技術”。
(3)構建體系化思維
體系化思維強調將事物、概念和關系組織成一個有條理、有結構的整體,能夠更全面、深入地理解問題本質,提供更有效的解決方案(體系化思維其實也是結構化思維的一種呈現,在這里推薦一本書《金字塔思維》,講的是從過程化思維向結構化思維升級的一些方式方法)。DDD的幾個核心概念,要求負責人不能只從單點去看問題,需要從線和面上去深入理解,這點能很好的幫助個人去構建體系化思維的能力。
五、DDD缺點
任何事物都一定存在正反兩面,雖然DDD在構建復雜軟件模型上,有天然的優(yōu)勢,但同時這套方法論的缺點也非常明顯:
邏輯相對簡單的業(yè)務和產品(比如一些小型公司的內部OA系統(tǒng)),用傳統(tǒng)的MVC架構會更適合,構建也更快速。
非業(yè)務形態(tài)產品和應用并不適合,比如bigdata。這類應用和業(yè)務專注于數據層的交互和適配,并無強業(yè)務語義類訴求,而DDD最關鍵的一部分就是業(yè)務領域的抽象和包裝,切記,它解決的是負責業(yè)務問題。
六、核心概念
DDD戰(zhàn)略+戰(zhàn)術全景圖
DDD的核心理念有兩部分,“戰(zhàn)略設計,戰(zhàn)術設計”,理解清楚了這兩部分,其實DDD的精髓也就理解了。但是在這之前,先簡單描述下DDD這套方法論的一個完整設計流程。
首先第一步,根據業(yè)務訴求,提煉出整體的業(yè)務流程,同時拆解出里面的關鍵事件,角色,參與者等核心實例。整個拆解和梳理的方法論,目前業(yè)界有一些比較成熟的,比如事件風暴,四色建模法等,后面單獨講。
提煉完整個業(yè)務流程后,進入戰(zhàn)略設計階段,這個階段主要是從全局和頂層的視角,把整個業(yè)務語義轉換為結構化分層。通過領域和子域的劃分,同時結合通用域、支撐域、限界上下文等設計,分解問題復雜度,其實就是前面說到的“分而治之”的思想。
接下來就會到具體的戰(zhàn)術設計階段,通過前面的戰(zhàn)略設計階段,已經把整個領域、邊界、上下文等關鍵模塊都梳理完成,現在就是從各個域中再次拆解更細粒度的模塊,去指導最終的編碼實現,這些更細粒度的模塊包括實體、聚合、聚合根等。
最后就到了編碼實現階段,DDD有一個關鍵價值,叫做“設計即實現”,所以在戰(zhàn)術階段的設計,理論上是可以直接作用于代碼的分層結構,如果架構和戰(zhàn)術階段有出入,說明之前的設計有問題,可以復盤重新推演。
以上就是最基本的一個的設計流程,要完整的理解這個流程,“戰(zhàn)略設計,戰(zhàn)術設計”兩個階段尤其關鍵,接下來先說明戰(zhàn)略設計(戰(zhàn)略方法論)的核心概念。同時整體的戰(zhàn)略和戰(zhàn)術設計,光描述有點抽象,我提煉了下整個DDD的分層架構,只保留了最核心的部分,后面理解完了整個理論知識和部分實戰(zhàn)后,可以回來再看這張圖,會更有體感。
1. 戰(zhàn)略方法論
(1)領域
領域(Domain)是指業(yè)務問題的特定領域范圍,它涉及到特定業(yè)務的規(guī)則、概念、業(yè)務流程等。領域是對業(yè)務問題進行分解和組織的基本單位。
(2)子域
子域(Subdomain)是指在一個大的領域中劃分出的相對獨立的子領域,它通常代表一個獨立的業(yè)務領域,具有特定的業(yè)務邏輯和功能需求。子域可以是整個系統(tǒng)的一個功能模塊,也可以是一個獨立的業(yè)務流程。
(3)通用域
通用域(Generic Domain)是指與特定業(yè)務領域無關的通用功能,它是在整個領域中被多個子域所共享和復用的功能。通用域包括一些通用的服務、工具、組件等,用于支持多個子域的實現。
(4)支撐域
“支撐域”(Supporting Domain)指的是與核心業(yè)務的實現和發(fā)展密切相關的非業(yè)務功能。這些支撐域可以包括安全認證、用戶管理、日志記錄等在整個系統(tǒng)中被多個子域所共享和使用的基礎設施功能。支撐域和通用域概念上有些類似,區(qū)分他們的標準簡單歸納下的話,支撐域是由外域提供的能力,通用域是本域提供。
(5)限界上下文
“限界上下文”(Bounded Context)則是DDD中的一個重要概念,用于劃分和隔離不同的領域或子系統(tǒng)。一個限界上下文指的是一個明確定義了特定業(yè)務領域所圍繞的邊界,它包含了領域模型、業(yè)務規(guī)則、相關的領域服務和持久化邏輯等。不同的限界上下文之間可以是相互隔離的,每個上下文內部有其自己的語言和模型,但是它們之間也需要通過明確定義的接口進行通信。
(6)小結
在DDD戰(zhàn)略設計中,首先需要進行領域建模,即通過與領域專家的合作和深入領域知識的研究,將業(yè)務需求轉化為領域模型。接下來,根據領域模型進行軟件設計和開發(fā),實現業(yè)務邏輯和功能。在整個過程中,需要保持與業(yè)務專家的緊密合作,不斷迭代和驗證領域模型的準確性和有效性。下圖是體驗VOC產品在做設計時的戰(zhàn)略架構:
某體驗產品的整體戰(zhàn)略設計
2. 戰(zhàn)術方法論
(1)實體
代表領域中具有唯一身份和生命周期的對象。實體有自己的行為和狀態(tài),并通過標識屬性進行唯一標識。
- 貧血模型:貧血模型是指領域對象只具有數據屬性,缺乏相關的行為邏輯。在貧血模型中,業(yè)務邏輯主要存在于服務層或者其它外部對象中,領域對象僅被視為被動的數據容器。這種模型在領域驅動設計(DDD)中被認為是反模式,因為它無法更好地體現領域的核心概念和規(guī)則。
- 失血模型:和貧血模型相似,指的是領域對象缺少業(yè)務邏輯和領域行為,以至于數據和行為的重要部分都被丟失。這種模型經常出現在面向對象的開發(fā)中,尤其是基于關系數據庫的實現中。
- 充血模型:充血模型是在領域對象中充分體現了業(yè)務邏輯和行為的模型。充血模型積極地包含了數據和相關的行為邏輯,它使得領域對象能夠更好地封裝與之相關的業(yè)務規(guī)則和行為,提供了更加一致和抽象的編程接口。充血模型是DDD中推崇的設計模式,使得領域對象能夠成為業(yè)務規(guī)則的中心。
- 漲血模型:漲血模型是指在充血模型的基礎上,進一步將領域對象的狀態(tài)和行為擴展到前沿技術和新的設計模式中(有些理念力,漲血模型和充血模型的區(qū)別在于,漲血模型添加了持久層的行為)。
充血模型雖然是DDD中推崇的設計模式,通過領域實體,一些關鍵行為和邏輯其實也能一起拿到了,但是在我的經驗中,我更喜歡使用貧血+充血的混合模型(或者叫充血模型的簡化版),因為這里涉及到一個標準的建立問題,如果只用充血模型的話,哪些行為和邏輯該下方到接口服務層,哪些又該收攏到實體中,這里面每個人的理念不一樣。而我的標準是,涉及到持久層和復雜行為都下放到服務層,簡單行為放到實體模型中。這樣有個好處,隨著業(yè)務的發(fā)展,如果只用充血模型,你的實體會越來越臃腫;如果只有貧血模型,自身又太單薄。所以一部分行為下放到服務層,我可以更細粒度的拆分服務接口,保證更優(yōu)良的邊界和代碼可讀性,同時也保證了模型自身的健壯性。
最后,不論哪種模型,都沒有絕對的好壞,能夠很好的定義出設計標準,同時基于自己的理解設計出符合業(yè)務擴展的實體和服務就是好的模型。
(2)值對象
代表領域中沒有唯一標識的對象,它的相等性是通過值的相等性來判斷的,而不是通過標識。比如地址信息,手機號碼,標簽屬性等。
(3)聚合根
聚合根是聚合的根實體,它是一組相關對象的入口點,管理著聚合內其他對象的生命周期和完整性。聚合根通過封裝聚合內部的對象,并定義了聚合的一致性邊界,確保聚合內的對象之間的關系和約束得到維護。外部對象只能通過聚合根來訪問和操作聚合內的對象,從而保證了聚合的完整性和一致性。
(4)聚合
一組相關對象的集合,由一個根實體(Aggregate Root)作為集合的入口點。聚合定義了一致性邊界,通過聚合根管理其內部對象的生命周期和完整性。
(5)領域服務
代表領域中的一些操作或業(yè)務邏輯,它不屬于特定的實體或值對象,而是為解決特定領域問題提供通用的服務。
(6)領域事件
代表領域中的發(fā)生的重要事件,可以用于通知其他領域對象或跨限界上下文進行解耦和協(xié)作。
(7)資源庫
資源庫是用于管理領域對象的創(chuàng)建、更新和持久化的接口。它實現了將領域對象從內存中存儲到持久化介質(如數據庫)中,以及從持久化介質中檢索對象并還原為領域對象的功能。資源庫隱藏了底層的數據訪問細節(jié),提供了一致的接口和抽象,使得領域對象的訪問和持久化變得簡單和統(tǒng)一。
(8)小結
DDD戰(zhàn)術設計是在DDD戰(zhàn)略設計的基礎上,著重于解決如何將業(yè)務需求和設計模型有效地映射和實現的具體方法和技術。它的目標是根據戰(zhàn)略設計的指導,通過合理的領域建模和架構設計,將領域問題轉化為高內聚、低耦合的代碼實現,從而更好地滿足業(yè)務需求。
某體驗產品協(xié)同域的戰(zhàn)術設計
七、領域建模
到這里,DDD的核心概念基本已經講述完?;谝陨系暮诵母拍?,接下來就是DDD最關鍵的部分——領域建模,它的目的歸納起來就一句話:提煉業(yè)務知識,形成統(tǒng)一語言,沉淀領域模型。
領域建模的優(yōu)秀與否,可以說直接決定著本次設計的成敗,因為一旦發(fā)生建模邊界不清晰,實體劃分錯亂,核心屬性沒有遵守開閉原則等問題,雖然當下可以正常交付業(yè)務,但是對于整個項目的后續(xù)發(fā)展可以說是災難性的(之前接觸過一個系統(tǒng),因為一個實體的關鍵屬性在最初設計時,沒有制定標準規(guī)范,語義不統(tǒng)一,造成使用混亂。最后不得以重新設計,結果造成上游的業(yè)務使用方全要配合改造回歸,不僅改造成本巨大,同時引發(fā)了P級故障)。
我最開始說的“優(yōu)秀的領域專家也是半個業(yè)務專家”,其實就體現在這一環(huán)節(jié),好的領域建模,前提一定是深刻理解完業(yè)務的,同時再次強調下這個觀點:領域建模,是基于現實,但不完全等價于現實。以下是領域建模的交付物:
- 領域模型:包含領域對象、屬性、關系、行為、邊界范圍等各個方面,用于描述業(yè)務的本質,這也是最重要的產出物。
- 用例圖:用于明確系統(tǒng)的功能。
- 數據模型:描述系統(tǒng)的數據結構和關系,包括實體關系模型、關系數據庫模型等。
- 狀態(tài)圖:用于描述系統(tǒng)各個狀態(tài)及其轉移條件。
- 活動圖:用于描述系統(tǒng)流程中的各個活動及其關系。
- 序列圖:描述系統(tǒng)中各個對象之間的交互過程和消息傳遞序列。
- 架構模型:包含系統(tǒng)的物理和邏輯結構,包括組件、模塊、接口等。
1. 事件風暴建模
事件風暴(Event Storming)是一種用于快速探索、理解和設計領域模型的合作工作坊技術。
它是由Alberto Brandolini于2013年提出的。事件風暴通過團隊協(xié)作的方式,以用戶的視角來討論和探索整個業(yè)務流程。參與者將自己的理解和知識通過貼在墻上的便利貼上表達出來,核心會圍繞著事件去編排整個業(yè)務流程。事件可以是任何對業(yè)務、系統(tǒng)或用戶有意義的事情,包括用戶觸發(fā)的操作、系統(tǒng)的狀態(tài)轉換、通信和消息傳遞等。這些事件以一種自頂向下的方式,以時間線的形式貼在墻上。隨著討論的深入,團隊可以探索和辨識出各種概念、實體、聚合根、資源庫、上下文邊界、業(yè)務流程和事件的關聯(lián)關系。這有助于更全面地理解整個領域的復雜性,并為后續(xù)的領域建模和業(yè)務流程設計提供線索和洞察。
事件風暴具有高度可視化的特點,能夠促進團隊之間的溝通和共享知識。它也可以幫助團隊快速理解現有系統(tǒng)的復雜性,并為系統(tǒng)的重構和演進提供指導。此外,事件風暴還可以用作需求分析、業(yè)務流程優(yōu)化和團隊協(xié)作的工具。
需要注意的是,事件風暴并非一種正式的建模方法,而是一種協(xié)作工作坊技術。它可以結合其他建模方法(如領域驅動設計)和工具(如UML、流程圖等)來進一步詳細和完善領域模型。在事件風暴中,沒有確定的固定語法,但是有一些常用的技術和簡寫符號,用于記錄和表示不同的業(yè)務事件和概念。
以下是一些常見的事件風暴語法和符號:
- 用戶角色:通常使用人物標簽或者角色名字來代表具體的用戶,例如 “客戶”、“管理員”等。
- 業(yè)務事件:使用動詞來描述業(yè)務活動或事件,如“創(chuàng)建訂單”、“審核申請”、“發(fā)貨”等。
- 識別的領域概念:在事件風暴中,通過寫在有色便利貼上來標記關鍵的業(yè)務概念,例如“訂單”、“產品”、“支付”等。這些概念有助于團隊識別和理解業(yè)務的重要方面。
- 粘貼便利貼:使用不同顏色的便利貼來表示不同的類型或者關注點。例如,可以使用黃色便利貼表示業(yè)務活動和概念,使用藍色便利貼表示抽象的過程和規(guī)則,使用粉色便利貼表示意見、問題或待解決的事項。
- 關系箭頭:可以使用箭頭來表示業(yè)務事件之間的關系,例如表示事件的先后順序、依賴關系等。
- 事件風暴的語法并不是嚴格規(guī)定的,而且可以根據團隊的需要和偏好進行適當的調整。重點是通過快速的頭腦風暴,來協(xié)作識別和探索業(yè)務領域的關鍵事件,以促進團隊的共享理解和協(xié)作。
事件風暴的本質上是通過腦暴的方式,圍繞關鍵領域事件串聯(lián)整個業(yè)務場景的生命周期,通過發(fā)散去收集,通過收斂去提煉,要真正把這個方法用好,有兩個關鍵點:
主持人的綜合能力,尤其體系在最后的收斂上,是否能把如此多的腦暴信息,提煉成關鍵點。
事件風暴是一個比較“重”的方法,對于一些0-1建設的大型項目(1000人日以上)比較適合,一些中小型項目有些“過渡設計”。
這個方法大家了解下就行,我不展開講,實戰(zhàn)中不常用
2. 四色建模
Peter Coad在他的書《Java Modeling In Color With UML》中,提出了一種與顏色相關的建模方法,被稱為Color Modeling。這種方法使用顏色作為一種可視化技巧,用于在領域模型中表示不同的對象和概念。它的目的是通過使用顏色來幫助開發(fā)者更清晰地理解和傳達模型的結構和關系。
四色建模的思想是通過使用不同的顏色來標識不同的概念和角色,以增加模型的可讀性和可理解性。每種顏色都代表一個特定的責任或角色,通過這種方式可以更好地定義和呈現領域模型的各個組成部分,使得開發(fā)團隊在理解和溝通模型時更加容易。
需要注意的是,四色建模并非DDD的核心概念或原則,它更多地是作為一種模型建立和可視化的輔助工具。DDD更關注于如何基于通用語言、領域模型和限界上下文等概念進行軟件系統(tǒng)的設計與開發(fā)。
以下是四色模型的語法:
- 時標原型(Moment-Interval Archetype,也稱業(yè)務關鍵時刻,簡稱MI):表示事物在某個時刻或某一段時間內發(fā)生的,如銷售訂單、收款記錄等,使用淺紅色表示。
- PPT原型(Part-Place-Thing Archetype,人/事/物原型,簡稱PPT):表示參與扮演不同角色的人或事物,如商品、賬戶、店鋪等,使用淺綠色表示。
- 角色原型(Role Archetype,簡稱ROLE):抽象了一種參與方式,由人或組織機構、地點或物品來承擔,如客戶、商家、財務組織等,使用淺黃色表示。
- 描述原型(Description Archetype,簡稱DESC):對上述顏色表示的內容進行解釋,用于分類或者描述建模過程中產生的數據、事件或者活動,使用淺藍色表示。
用一句話來概括四色原型就是:一個什么樣的人或物品以某種角色在某個時刻或某段時間內參與某個活動。其中“什么樣的”就是DESC,“人或物品”就是PPT,“角色”就是ROLE,而“某個時刻或某個時間段內的某個活動”就是MI。按照這個邏輯,整體流程如下:
- 建立時標原型:尋找需要追溯的事件,根據追溯事件尋找足跡。
- 建立PPT原型:豐富模型,尋找時標原型周圍的人/事/物,使它可以更好地描述業(yè)務概念。
- 建立角色原型:進一步從中抽象出可以參與到不同流程中去的角色。
- 建立描述原型:把一些信息用描述對象補足。
八、建模實例
就結合剛說的四色建模來演示,否則光說還是不夠有體感。我以目前負責的“某體驗平臺(簡稱VOC)”結合四色建模法來具體演示下。
1. 梳理業(yè)務流程
首先描述下VOC的背景和目的,一句話:
站在橫向和全局的視角,快速發(fā)現用戶在得物系產品使用過程中發(fā)生的體驗問題,同時及時定位,解決該問題,最終提升用戶體驗。
以下是之前某大廠的體驗中臺的目標描述,和VOC類似。
為了能達成上述目標,我們究竟應該怎么做,或者說具備什么樣的能力呢,總結下來其實是以下幾點:
具備收集用戶所有原始“聲音”的能力,否則我們無法從全局的角度去分析這個事情,這里的原聲渠道需要盡可能多的涵蓋用戶想表達訴求的入口,才能全面,比如在線咨詢、熱線咨詢、工單、評價等。
有了聲音之后,我們需要具備分析聲音,同時通過聲音提煉出具體問題的能力,讓分析人員能夠快速精準的判別用戶的問題是什么。
同時平臺也應該具備快速及時的前置發(fā)現問題的能力,把這些重要的、緊急的問題通知到關鍵人員手上,讓他們第一時間知曉。
最后,不管是主動分析出問題,還是收到了重要的問題通知,都應該立即著手處理這些問題。同時因為這些問題涉及的業(yè)務,bu,歸屬都不盡相同,所以處理的方案和流程也應該體現不同,這也衍生出在協(xié)作處理過程中,鏈接的上下游平臺應該會非常多,處理動作和內容會很豐富。
根據以上的分析思路,我們可以把整體的業(yè)務流程梳理出來,同時結合四色建模法,我們把除DESC的其他關鍵元素體現到流程里(為了便于理解,我畫的是比較粗的流程,實際流程會比這個復雜):
體驗VOC產品業(yè)務流程
從圖中可以明顯看出來,這個流程的關鍵四色要素:
- 時標原型:用戶原聲、原聲問題明細、預警單等,表述某一時刻產生的關鍵事件,一般是運行態(tài)的實體。同時基于VOC的業(yè)務,我們分別劃分了3個階段:分析問題、定位問題、解決問題。同時結合上面的思考,最關鍵的幾個時標原型分別是分析階段的用戶原聲,定位階段的預警單,解決階段的協(xié)同單(按照戰(zhàn)術方法論,這3個時標原因就是聚合根)。
- PPT原型:數據渠道、分析視圖、問題標簽模板等,一般是配置態(tài)或維度相關實體。
- 角色原型:系統(tǒng)、運營管理員、分析師等,這塊比較好理解,使用產品的角色(一般可以不把系統(tǒng)角色放進去,這里放上去是為了便于理解)。
有了這個基本的業(yè)務流程和關鍵要素后,接下來進入概念模型的設計階段。
2. 建模-概念模型
首先什么是概念模型,一句話總結:概念模型是一個高層次的抽象模型,獨立于具體實現的領域模型,它關注業(yè)務領域的核心概念和關系,以及團隊之間的共享理解。
一般我們做建模設計的時候,很多經驗豐富的領域專家會略過這一環(huán)節(jié),直接抵達領域模型的建模階段。當然,這并無任何不妥,因為我們最終在做軟件開發(fā)和編碼的時候,必然是基于具體的領域模型去設計的,但是概念模型對于整體建模流程來說,任然非常重要,主要體現在以下幾點:
概念模型因為是更高層次的抽象,所以只表述核心的概念和關系,不表述細節(jié)和完整實體,所以會更簡單,清晰。
團隊之間交流共享時,尤其是在和業(yè)務,產品同學交流時,他們往往不會太過關注細節(jié),用概念模型來交流理解會更合適。
概念模型一般用在一級域的設計上,它必須要體現全局性,整體性。所以它是具備方向上的指導意義,我建議在新的一級域項目建設初期,一定要做概念模型的建模(像交易、商品、營銷、體驗、客服這些都屬于一級域)。
回到主線,基于第一步我們梳理完的業(yè)務流程和四色要素,我們做下編排,圍繞著上述3個關鍵時標原型為核心,結合其他幾個要素和關系,即可得到體驗VOC的完整概念模型。
某體驗產品概念模型
3. 建模-領域模型
在完成概念模型的設計后,終于到了我們最終的環(huán)節(jié),也是建模流程里最重要的階段——領域建模。具體的領域模型是在概念模型的基礎上進行具體的實現,除了表述清楚核心概念和關系外,還需要能夠表達非核心的實體關系的能力,同時它還是指導技術實現的標準。
基本上完成這個階段后,微服務拆分、代碼架構的設計、模塊劃分、核心流程也就確定了。
我們做領域建模時,一般會按照一級子域做拆分,一般一級子域代表了一個完整的業(yè)務域,獨立解決一類業(yè)務問題。參考“體驗VOC產品的整體戰(zhàn)略設計”部分,我們劃分的是洞察子域,協(xié)同子域,預警子域和問題子域,所以理論上會拆分4個微服務應用,同時各自去做自己子域的領域建模。
下面我例舉其中的協(xié)同子域來做演示。整體的建模思路如下:
第一步:定義解決標準。
首先,協(xié)同域的目標是高效的助力業(yè)務解決問題,那邊這里就涉及到如何解決,用什么樣的方案解決,解決的流程是怎么樣的,誰來解決。首先要確定這個解決標準,我們抽象為“協(xié)同方案”,他的核心就是制定解決標準,包括我剛描述的那一系列要解決的問題。
第二步,根據解決標準,定義執(zhí)行標準。
有了解決標準后,具體如何解決,這個時候我們就需要有個根據解決標準(協(xié)同方案)履約的載體,他會按照方案上制定的流程,處理人,解決方式等去流轉,這個載體我們抽象為“協(xié)同單”。
第三步,圍繞著上述兩個標準,去完善域邊界,實體關鍵屬性,周邊實體和關系網。
比如,協(xié)同方案里的流程,我們是希望抽象成獨立模版做復用性,還是一個方案就代表了一個流程(協(xié)同流程)?協(xié)同單履約當中的所有記錄是否需要留痕和外化,那是否需要提煉一個服務記錄的概念(協(xié)同記錄)?流轉里的內容呈現是否需要單獨抽出來,做成業(yè)務可自定義配置化(表單模版)?協(xié)同方案和協(xié)同單應該是怎么樣的關系?等等這所有的業(yè)務邏輯,都需要反映到領域模型中表達出來。
最終以上三步完成后,整個協(xié)同域的領域模型也就基本確認好了。因為協(xié)同域不復雜,領域模型結合實際做了簡化,所以就沒有表示核心的領域服務,限界上下文等概念。具體呈現如下:
九、總結
對于領域驅動設計來說,應該遵循一個道理:不拘于形式(有點類似電影里的,劍客最高的境界是身邊無劍,但是任何所見皆可為劍的感覺)。文章的前面部分,我講了許多的概念:聚合根、值對象、領域事件、限界上下文等,但是實際設計開發(fā)過程中,并不需要照搬全套的體現出來,只要能夠表達清楚核心的實體和關系、清晰的邊界和合理的擴展性即是好的領域設計。當然這篇文章主要是理論部分,實戰(zhàn)部分我還是想先把戰(zhàn)術設計的全貌先展現一遍,最終再做精簡,這樣可以既知全貌,卻不教條。
同時我再強調下,合格的技術專家一定是半個業(yè)務專家,而DDD這套方法論,可以讓技術同學很好的去全局理解業(yè)務形態(tài),同時以結構化的思維去抽象業(yè)務概念,既能提升全局的認知高度和架構能力,也能加強細節(jié)把控力,所以它是一套很好的軟件設計復雜性解決之道。
最后回到最初那個問題,一個FBI(數據看板系統(tǒng)),一個電商交易系統(tǒng),它們都適合用DDD嗎,為什么?
本文由人人都是產品經理作者【湯師爺】,微信公眾號:【架構師湯師爺】,原創(chuàng)/授權 發(fā)布于人人都是產品經理,未經許可,禁止轉載。
題圖來自Unsplash,基于 CC0 協(xié)議。
- 目前還沒評論,等你發(fā)揮!