【多圖預警】手把手教你用“DDD”的思維構建產品架構 | 附詳細案例
編輯導語:邏輯思維對于構建產品架構十分重要,產品架構設計是一個系統化的大工程,對于個人能力也有一定的要求,本篇文章作者分享了用“DDD”的思維來構建產品架構,結合作者的設計理念總結出了一套完整的方法論,一起來學習一下吧,希望對你有幫助。
最近帶的產品經理請教我如何思考并繪制產品架構圖,他在網上看了一些文章,要么大段概念介紹,無法實操,要么不好理解,所以想問問我有沒有什么經驗。
其實關于產品架構的設計,我自己基于“領域驅動設計(DDD)”理念,創造了一套“一二三四”模型,不知是否具有廣泛性和應用性,遂整理成文,并附加案例,供大家討論并驗證。
一、前言
作為產品經理,只專注于功能設計是不夠的,需要清楚地了解產品的定位、要解決的問題、系統的組成、每個系統承擔的角色以及未來的發展,因此對產品的架構能力必不可少。
當我剛開始負責一個產品的時候,對于產品架構的要求不是那么明顯,覺得那只是換了一種漂亮的形式來展現系統中的功能。而且也不注重前期的規劃,往往是要做相關的材料,才根據現有的系統反推架構。
但是隨著產品的發展,出現了一些之前沒有考慮到的需求,此時再去加新功能,難點不在于要怎么設計,而是如何兼容已有的設計,久而久之,產品邏輯會越來越復雜,牽一發而動全身,最終只能重構,不管是對設計還是對開發都是如此。
當我開始負責一條業務線的多個產品的時候,又發現不同產品之間會有相同的功能模塊,但是他們是分別開發的,可能邏輯不同,也可能技術方案不同,造成這樣原因有很多,比如溝通問題、制度問題等,但最重要的還是由于對新需求“打補丁”的方式導致產品越來越臃腫,一些共用的模塊無法抽離出來,所以形成了重復造輪子的情況。
以上,讓我越來越明白前期設計好產品架構的重要性,同時糾正了我的一個思想:產品架構設計是一個系統性的工程,不是隨便羅列功能模塊就能完成的。
我開始研究方法論,看了一些文章,每個人都有每個人的看法,但尚沒有一種權威的理論作為支撐。
于是我嘗試跳出產品范疇,去看看旁邊比我們先發展好幾十年的開發領域,試圖從中找到一些靈感。
近年來技術架構都在圍繞“高內聚低耦合”的思想不斷完善,從MVC、三層架構到微服務、中臺、DDD,無一例外。
其實對于產品架構來說也是一樣,在設計系統時不僅要考慮全面,還要考慮未來的可拓展性。
本文介紹了我在研究“DDD”后,借助其通過分解控制復雜性的思想,并結合自身經驗總結的一套構建產品架構的方法論,我將其命名為“一二三四”模型。
二、一個【關鍵鏈路】
客觀世界中,存在能量守恒定律,一種物質通過周圍環境的影響會變成另一種/幾種物質,但總能量不會變。如果我們把環境因素想象成一個黑盒,那么可以抽象出下圖模型:
同理,我們將互聯網產品也想象成一個黑盒,它并不會創造新事物,而是通過將事物線上化和協同化,并通過數據智能的方式加速“輸入→輸出”這一過程,從而為用戶提升效率、創造價值。
任何一個產品不管它現在發展得有多龐大,都有且存在著一條關鍵鏈路,用來連接各實體。
比如在沒有滴滴前,我們是靠運氣打車,乘客和司機之間不存在其他的聯系。
而滴滴是將周圍的司機、周圍的車輛和需要打車的乘客都聯系在了一起,從而提升了打車體驗。
盡管現在的滴滴已經不止“打車”業務,還發展了貨運、順風車、代駕、共享自行車、金融等其他業務,但都是在這條關鍵鏈路上,對輸入和輸出進行擴展。
所以在繪制產品架構圖之前,應該先思考:你所負責的產品,它的核心鏈路是什么,連接了哪些實體?
這樣做有兩個好處:
- 避免其他干擾,直擊產品核心價值,類似于“第一性原理”;
- 不需要對業務很熟悉,只要有產品定位,就可以得到。
例如在疫情當下,高校無法組織線下考試,因此需要做一個線上考試平臺,即便你以前沒有接觸過教育信息化行業,你也知道考試的輸入是考生、考官和試卷。
值得注意的是,產品的核心鏈路不是一成不變的,它會隨著產品定位的變化而變化,比如下圖是小紅書歷次slogan的變化,每一次定位的變更都意味著輸入和輸出的調整。
三、兩個【思維】
找到了核心鏈路,接下來就是利用“分解思維”對核心鏈路進行梳理,并利用“聚合思維”對系統進行構建。
1. 分解思維——6W2H
通過第一步,我們找到了與系統相關的、最直接的輸入和輸出實體,接下來就是分析實體與實體、實體與系統之間的聯系。最全面且有效的方法就是6W2H:
1)分解輸入
回到線上考試系統,先按照上圖的方法分析試卷:對于輸入,我們要尋根溯源,思考它從哪來,如何來、與系統的關系等。
- what(屬性):試卷類型、分值;
- who(誰參與輸入):出題老師;
- when(什么時候輸入):考試前;
- where(從哪來):題目;
- how(怎樣輸入):創建、導入;
- how much(數量受什么影響):考試方式。
通過以上分析,我們新發現了兩個實體:出題老師和題目,需要繼續對其分解至最細(見下圖),過程中可省略一些維度(考生、考官也按照相同的辦法進行分解,此處略)。
2)分解輸出
對于輸出的分解思路會有少許不一樣:我們要發散思維,思考它到哪去,如何去、如何擴大輸出等。
- what(屬性):考試模式、考試時間、考試公告;
- who(誰參與輸入):學校負責人;
- when(什么時候輸入):考試前;
- where(到哪去):考場。
同樣對找出的實體用相同方法進行再分解:
至此,我們已經有了一個非常龐大的包含各角色、各事物及信息流轉方向的對象關聯畫布。
2. 聚合思維——劃分子域
如果把我們面對的問題叫做“領域”,接下來,就要利用聚合的思想將一個或多個分散的實體封裝為一個整體,使“領域”劃分為幾個“子域”(子系統)。
在領域驅動設計思想中,關于如何聚合可遵循以下四個原則:
- 生命周期一致性原則
- 問題域一致性原則
- 場景頻率一致性原則
- 聚合應盡可能的小原則
翻譯成產品經理能聽懂的話就是:
- 實體A脫離另外一個實體B是否有存在的意義。例如如果沒有考試,那么也就不存在考場
- 不屬于一個問題域的實體不能放在一起。比如在線監考和在線考場,根據生命周期原則可能會把這兩個實體放在一個子域,因為有正在進行的考場才需要監考,但實際上他們解決的是兩個不同領域的問題
- 實體A和實體B能否被同時操作。以“試卷”、“考場”和“題目”為例,試卷包含了很多題目,這些題目會通過線上考場展示給每個考生。但是,站在操作層面,如果你要查看試卷列表,其實并不需要關心里面的題目,也不需要了解試卷所在的考場。盡管考務人員在編排考場的時候會查看題目以驗證是否添加正確,但是大多數時候并不會去查看題目的分數,更不可能在創建考場的時候修改題目
- 剩余的實體均劃分成單獨的子域。
- 好的劃分可以讓整個系統更靈活,拓展性更高。但是也不能一味追求分化,需要根據自己業務的實際場景去衡量。還是拿題目和試卷舉例,如果你的業務比較簡單,只需要對試卷進行操作,那么可以把題目和試卷劃分為一個“試卷子域”;如果你的業務復雜,試卷既可以直接創建,也可以通過題目組卷,那么就需要劃分為兩個子域“題庫子域”和“試卷子域”。
因此對于線上考試平臺可以做如下劃分:
3. 分解思維——界限上下文
在DDD中,對界限上下文的定義是:動態的業務流程被邊界靜態切分的產物??梢院唵卫斫鉃樵俅卫梅纸馑季S把每個子域內涉及到的模塊分解出來(此處不一一舉例)。
4. 關于該步驟的答疑
個人認為,本部分是本篇最重要也是最難理解的內容,因此有必要做一些解釋。
我做過幾個從0-1的產品,在進行用戶調研前,首先會提前構思好可能的業務流程,再通過調研去驗證和補充。因為沒有相關業務經驗,提前想的流程就會不全面,在這種情況下我開始尋找一種能夠快速熟悉業務的方法。
經過不斷總結經驗,我發現任何一個產品都只會關注于一個基本問題,所以我直接從這個基本問題入手,找出相關的輸入輸出,再通過各個維度的不斷分解,不僅能找到所涉及的所有實體和過程,同時還找到了他們之間的聯系(業務流程)。各位看官不妨一試。
四、三個【完善】
一個系統要想好用,有完善可拓展的功能只是第一步,還必須保證系統的穩定性和安全性。
這些不只是技術人員需要考慮的問題,產品經理也需要設計相應的產品架構、業務流程和功能邏輯來規避這些問題,有時甚至要犧牲用戶體驗。
在穩定性上,我們已經從業務的角度把一個大系統劃分成了一個個高內聚、低耦合的小模塊,接下來就要從運行維護的角度考慮如何檢測預警以及出問題時的上報和解決。
此外還要找出所依賴的第三方服務,做好及時監控和應急方案,下圖是我在網上找的通過設計維護穩定性的兩個例子。
同樣在安全性上,除了要保證基本的數據安全、網絡安全,產品經理還要做一些提升安全性的設計,如二次認證、CA加密、二級密碼等。
五、四個【層次】
至此,我們已經將整個業務劃分出了多個領域(系統/模塊),接下來就是縱向地對層次進行劃分。
這里先介紹一下產品層面的三層架構(雖不是但源于技術層面):
- 表示層:與用戶直接接觸的軟件和硬件形態
- 業務邏輯層:通過上述步驟劃分出來的各領域模塊
- 數據層:使用到的數據庫和數據服務
這種架構本身沒有什么問題,但是如果站在更高的視角看整個產品矩陣,你會發現隨著業務場景越來越復雜,每條業務線都會變得非常臃腫,并且業務線與業務線之間會存在重復造輪子的情況。
比如公司要做一個企業培訓的新業務,其中題庫、試卷模塊可以完全復用考試系統(類似于技術開發中的“組件”“中臺”概念),但在現有三層架構下不好進行抽離。
因此在設計產品架構時,還要根據產品經理的經驗,對業務依賴性不高,通用性、復用性較強的子域單獨抽離出來,組成新的一層——通用業務層。
- 表示層;
- 業務邏輯層;
- 通用業務層;
- 數據層。
至此,我們將上述步驟得出的結果進行整理,再找設計同事幫忙美化一下,即可得到下圖:
六、總結
- 一個關鍵路徑:找出核心的輸入輸出;
- 兩個思維:分解出各實體,聚合出各子域;
- 三個完善:考慮穩定性、安全性、第三方服務;
- 四個層次:按表示層、業務邏輯層、通用業務層、數據層劃分。
本文由 @產品亂彈 原創發布于人人都是產品經理,未經作者許可,禁止轉載。
題圖來自Unsplash,基于CC0協議。
結合自己的經驗,談下理解:
1. 劃分“領域”:其實領域就是一個一個的業務模塊,或者說一條一條的業務流。這些業務流來自業務問題,表示從問題到解決的過程。
2. 高內聚&低耦合:
i) 一個問題由實體+數據組成。
ii) 實體:由一些靜態的屬性組成,這些屬性基本不變或很少發生變化,例如一個用戶、一個組織、一個商品、一個項目都可以是一個實體,實體內部是高內聚,外部一定是低耦合的。
iii) 數據:即實體在一個業務過程的產出。例如客戶這個實體,在訂單業務流中,產生了訂單的數據。一條數據會引用多個實體的屬性,例如訂單數據會引用商品、客戶、業務員等等各種實體的一個或多個屬性。數據是動態產生的,所以一定是對應一個時間點的。由于數據的通用性,所以一定是統一使用數據庫來操作&存儲。
iiii) 業務流:其實業務流就是各個“領域”(可大可小,小到一條業務流,大到整個公司的管理&商業模式),業務流就是產品/解決方案黑盒,輸入&輸出都是實體+數據。
3. “中臺”:不管是業務中臺,數據中臺,都是為了解決“通用性”的問題,避免重復工作。
其實永遠沒有標準的答案,第一性原理只有一個:產品用來解決一個核心問題。
還沒看完,就直呼牛比了
這種思維在我們國家是比較先進的,期望有機會一同交流
6