領域驅動設計之我見-領域建模
前面兩節絮絮叨叨重點講了一句話:領域驅動設計的核心在領域模型,領域建模核心在精通領域業務。那麼該如何做好領域建模呢?需要精通的能力都沒有捷徑可走,但是也不是沒有方法可循,下文就領域業務和建模兩方面做一下講解。
做好領域建模,首先要做的工作是要精通領域業務知識,那麼領域業務知識從哪裡來呢?前面章節講了從事軟體研發的工程師並非全部來自於科班出身的學生,有些計算機相關學科天然帶著領域業務知識,例如GIS專業。這些專業的學生從事該專業類軟體開發,首先已經具備了該領域的專業知識,在進行需求調研、整理,以及內部溝通時使用的都是通用的語言,大家對於模型應該是什麼樣已經達成共識。
而對於現在從事網際網路軟體開發,我們面對的業務領域也許是一個全新的領域,是產品經理基於使用者痛點,構思的一個全新的軟體工具,此時,我們該如何構建我們的領域模型呢?領域模型,一定是一個名詞,那麼我們就可以以此為出發點,列舉軟體用使用到所有名詞,然後對名詞進行分類,再對歸類到同一型別的眾多名詞進行提取核心名詞,然後畫出核心名詞和該類別中的其他名詞之間的關係圖,最後抽象出該類別名詞擁有的動詞。
以支付系統的使用者資訊為例,第一步列舉所有名詞,並進行分類;第二步提取各組關鍵詞;第三步抽象出各個領域的動詞,如下圖:
領域模型劃分儘量保證業務的高內聚和低耦合,劃定領域邊界,保證一個業務邏輯儘量在一個領域模型內部,領域模型之間儘量少業務來往,領域模型劃分儘量保證,一次業務流程涉及儘量少的領域模型。
領域模型的構建過程中必須要業務專家/產品經理保持實時溝通,在模型的構件上保持統一的語言。最近在讀金字塔原理,其中講到歸納性思維和演繹性思維,人的原始思維方式是演繹性思維,這就決定了,我們經常會基於流程的去思考問題,而面向物件建模恰恰需要的是歸納性思維。如果我們研發採用面向物件思維構建軟體,而業務專家/產品經理基於業務流程的方式和我溝通,勢必驢頭不對馬嘴。
做好領域驅動設計,必須在領域建模時叫上領域專家/產品經理一起討論設計,保證所有參與產品設計開發測試的人員,在統一的領域通用語言層面溝通。例如,產品經理會和我們講使用者找回登入密碼,使用者第一步要怎麼做,第二步要怎麼做,第三步要怎麼做,最後得出什麼效果。而基於領域模型的通用語言應該是登入密碼應該擁有找回密碼的動作,完成該動作需要做第一步、第二步、第三步。
對於已經做了很久基於流程模式做軟體開發的工程師,轉向領域建模需要一個適應過程,基於流程開發和基於模型開發是兩個完全不一樣的思維方式,我們需要將程式碼的業務邏輯封裝在一個物件中,而不是流程中。對於spring這樣的框架構建起來的系統,整個工程中全部採用單例模式,滿屏的事務指令碼,需要的程式碼邏輯信手拈來,而基於領域模型的程式碼中,任何一個業務邏輯需要細心的打理,將業務封裝在最恰當的領域物件中,因為該邏輯只能在整個工程中存在一處,而且要保證該業務邏輯儘可能少的跨領域模型。既然使用領域模型開發這麼麻煩,那麼為什麼還要採用領域模型的方式開發呢?因為領域模型能夠比事務指令碼更好的管理大型業務邏輯。