蚂蚁金服对研发高要求的领域建模能力是指什么?
作者 | 騎著金牛往前走
出品?|?獨自慎思
0 前言
最近,由于工作需要,我接觸了網商銀行的一個項目。項目里對應的業務模型設計,是我工作這三年來見過的所有模型里最復雜的。于是,利用五一這個短暫的假期,我溫習了一遍領域建模相關的知識,對于領域模型的設計,有了一些額外的思考。
在領域界有一本書 《Domain-Driven Design》,是Eric編寫的,這本書在Goodreads上的評分是4.15分(相當高)。書中有這樣的一段話:
“軟件開發人員幾乎總是專注于技術,把技術作為自己能力的展示和成功的度量......當領域很復雜時,這是一項艱巨的任務,要求高水平技術人員的共同努力。開發人員必須鉆研領域以獲取業務知識。他們必須磨礪其建模技巧,并精通領域設計。“?
書中所強調的領域設計的能力,是對技術人員綜合能力評估的一種體現。在我看來,這是屬于在軟件工程這個方向中,T-1級別的能力。而所謂的領域建模,是一種通過日常不斷實踐,來強化開發人員思維,逼迫開發人員進入深度思考的過程,并通過在這個過程中的不斷錘煉,可以使得開發人員形成結構化思考方式的方法論。
但是,需要注意的是,領域模型本身的定義,在不同的方法論和流派中,是有一些區別的。領域建模的方法也有多種。不過,求同存異,沒有對錯之分。
在本文,我主要是寫一寫我對于領域建模的理解,以及介紹一些基礎的領域模型知識。算是對這個五一長假以及過去幾年工作經驗的一個總結。也會簡單提提,如何將領域建模的思路,與我們的日常生活結合起來思考。希望能對各位有所幫助。
ok, start with why.
1 領域模型
1.1 領域模型是什么
在why之前,我們先插入一個what,介紹一下領域模型的基本概念。
領域模型是對領域內的概念類或現實世界中對象的可視化表示。又稱概念模型、領域對象模型、分析對象模型。它專注于分析問題領域本身,發掘重要的業務領域概念,并建立業務領域概念之間的關系。———摘自度娘
這么解釋看著有點迷糊,簡單地說,領域模型,是用來描述事物本身的一個模型。它關注事物的特征,事物之間的聯系。由于在日常業務開發中,所面臨的場景是多樣化的,所以可能同一個事物,在建模過程中,我們所獲取的特征是不一樣的。例如某人A,他是員工,是程序員,是男人,也是父親。在特定的場景下,我們只提取指定的特征即可。
領域模型之間的聯系,我們要怎么理解呢?
以上面這位某人A為例,本次我們所要提取的特征,是父親。父親與母親,丈夫與配偶,關系是1對1的。也就是一夫一妻制。父親與孩子,關系是1對N的,一位父親,可以有一個孩子,也可以有多個孩子。母親與孩子的關系,也是1對N的。所以這一家三口之間的聯系,可以簡單用這張圖來表示:
當然領域模型的圖形化還有很多種方式,例如UML類圖、狀態圖、時序圖等,這邊就不一一介紹。
1.2 為什么要學習領域模型
“基礎設施決定上層建筑” —— 馬克思。
老祖宗教導我們,萬丈高樓平地起,告訴我們建高樓,要深地基。倘若把一個軟件比喻成一棟高樓,那么領域模型,就可以理解為高樓地下的基礎設施。
從架構上來說,領域模型是處于應用架構的最底層,上圖的Domain層,這一層涵蓋了模型治理、流程抽象、流程治理等方面的知識。我們可以很清楚地看到,如果領域模型沒有把控好,那么就相當于大樓地基沒有打好,帶來的后續建筑或是維護成本之高,是難以想象的。
Problem space 與 Solution space,是一套通用的問題分析解決方法論。如果我們以Problem space 與 Solution space來理解的話,領域模型所做的事情,是處于Problem space階段的,而Solution space 對應的則是系統模型。
領域模型與系統模型之間,我們要如何區分呢。
很簡單,領域模型專注的還是事物本身,是高度抽象的。到了系統模型,就是到了具體的設計階段。還是以上面的某人A為例,他有三個孩子,那么我們在設計階段,要去怎么建立系統模型呢?可以有以下這三種方案:
-
父親表里有多個孩子字段,孩子1、孩子2、孩子3,用于保存孩子的信息
-
父親和孩子是兩張獨立的表,通過外鍵關聯
-
通過字符串的格式存儲,例如搞個大json串,放在父親的表里
這是三種不同的實現方案,但是在領域模型層面,依舊是父親與孩子,是1對N。
所以,我們是通過領域模型,進而推導出系統模型,設計出對應的解決方案的。如果領域模型初期建模有比較大的問題,可能就會導致開發人員做很多的無用功。
但是我們為什么要按照這種流程來做開發呢,語言有面向過程和面向對象之分,我們可以對應到開發流程上,也可以理解有面向過程和面向對象(模型)之分。前期不做分析與設計,腦海中有個初步的實現思路,直接操起鍵盤一把梭,豈不是很暢快?而且從物理學的角度來看,系統的演變,隨著時間推移,混亂度總是不斷增加的(熵增),難道說領域模型可以做到熵減這種反科學的能力么?
讓我們來回憶一下這兩個場景,看看你是否遇到過:
1、接到PD的需求,大概看了一眼,操起鍵盤一把梭,梭了一階段以后,發現了某個環節存在問題,可能是PD的需求有不足,也可能是你實現方案存在局限性,找PD撕逼討論過后,發現需求入口側得不到解決。就只好推翻已有結果,從頭再來。或者是寫出一坨非常惡心人的代碼,告訴自己后面有空再重構。
2、應用上線運行了一段時間后,PD想做個小優化,過來找你討論。你發現雖然是個小優化,卻有大的改動。原因是你之前設計方案,不能夠很好的支持這次變更,或者說沒有很好地和PD需求連接起來。結果導致代碼越改越亂,難以維護。
當然,這么做,可能PD看到你為了她的小改動天天加班,心里過意不去,左一杯奶茶右一杯果汁,接觸得多了,一段職場姻緣就此開始。
如果我們選擇使用領域建模,這種自上而下的設計,能徹底解決上面的這兩個問題么?
答案應該是不能的,要解決上面的兩個問題,除了開發自身建模能力的提升之外,系統的設計能力、PD對于模型的理解能力,以及PD和RD之間的溝通有效性,都是值得考量的因素。但是,通過領域建模,我們至少可以保證代碼的實現與層級結構是相對科學穩定的,符合業內規范的。在領域建模的過程中劃分清楚域的邊界,對于后續的系統穩定性提升、依賴區分、業務邏輯清晰性,都是有很大的幫助的。(領域建模能力在螞蟻金服的某BU,是作為應用架構高P的考核標準之一)
所以做好領域建模,不止是提升開發人員的綜合素質能力,也是設計出可以低成本維護的可持續發展的穩定系統的必備要素。而領域模型到系統模型這一設計指導方針,可以幫助我們降低軟件設計與現實需求的差異性。
1.3 如何進行領域建模
進行領域建模的方式是有多種的。需要注意的一點在于,領域建模不是純粹的技術,不是簡單學習后就能設計出完美的模型。設計出好的模型,需要依賴于大量的經驗和思考。下面介紹給出一些常見的分析方法,然后我們選擇一個比較有趣的方法進行深入介紹。
常見分析方法
-
用例分析法
-
DDD(Domain-Driven Design)
-
DoDAF
-
四色建模法(Java Modeling In Color With UML)
-
飛馬模型(螞蟻金服內部)
例子
我們以用例分析法為例,這是最常見也是最簡單的分析方法。
用例描述:金牛發布了一篇文章。
這個用例似乎有點太簡單的,從主謂賓的角度來看,主語是金牛,謂語是發布,賓語是文章。
在這里我們補充一個點,領域模型是一個模型,模型本身是有屬性的。例如上面的某人A例子,他是一個人,那么就會有年齡、性別、身高等屬性。
為了引入屬性這個概念,我們給上面的用例描述加上定語。
用例描述:金牛發布了一篇領域建模相關的文章。
主語:金牛,名詞,可抽象為領域模型;謂語:發布,動詞,可抽象為模型關系;定語:領域建模相關,形容詞,可抽象為模型屬性;賓語:文章,名詞,可抽象為領域模型;當然,實際的用例描述會比上面這個復雜得多,具體的語與用途也會有更多映射關系,例如我們除了可以將定語抽象成賓語的屬性外,還可以將其抽象成賓語的關聯模型。
這時候我們根據上面這個簡單的用例描述,就可以抽象出一個簡單的領域模型,如圖:
整個流程是很清晰易懂的。我們來抽象一下具體的步驟:
-
收集用例描述集合
-
一系列需求文字描述的用例集合
-
-
尋找概念
-
對用例描述進行語言分析,識別名詞
-
-
添加模型關聯
-
名詞之間存在語義聯系,則往往存在模型關聯,例如上面的發布,聯系了金牛和文章兩個名詞
-
-
屬性完善
-
形容詞完善,例如上面的領域建模相關,如果文章存在標簽屬性,那么它的值在我們這個用例里就是領域建模。
-
簡單的步驟就是這四個,然而實際的工程中領域建模,遠遠比這個復雜。例如還存在子域劃分、模型組合等手段。
接下來我們來看一個比較有趣的例子,內容來自于《Object-Oriented Analysis from Textual Specifications》論文,中文翻譯為《基于文本規范的面向對象分析》,文章所講的內容,是如何通過自然語言處理技術,從語義和句法的角度分析用例描述,進而通過程序提取出領域模型。
用例描述:
the Static Requirements are: Vendors may be sales employees or companies. Sales employees receive a basic wage and a commission, whereas companies only receive a commission. Each order corresponds to one vendor only, and each vendor has made at least one order, which is identified by an order number. One basic wage may be paid to several sales employees. The same commission may be paid to several sales employees and companies.
the Dynamic Requirements are: A monthly payment is made to vendors. When a vendor makes a sale, he/she reports the order to the system. The system then confirms the order to the customer, and orders are delivered to customers weekly.
分為static requirements 和 dynamic requirements,靜態需求與動態需求。人工翻譯一下,大意內容是:
靜態需求:供應商可能是銷售人員或者公司。銷售人員收取基本工資和傭金,而公司只收取傭金。每個訂單只對應一個供應商,且每個供應商已經至少制造了一個訂單。訂單由訂單號進行標識。一份基本工資可以支付給幾個銷售人員。同樣的傭金可以支付給幾個銷售人員和公司。
動態需求:每個月向供應商付款,當供應商進行銷售時,他會向系統報告訂單。然后系統確認訂單給客戶。訂單每周完成對客戶的交付。
這個例子會比一開始舉例的發布文章復雜一點,我們還是用回上面的簡單四個步驟。標記出以下名詞:vendor, order, sales employee, company, order number, basic wage, commission.
這些名詞,有一些是主語,一些是賓語。我們再結合動詞,能畫出這樣一張圖
有些名詞,可以作為另一部分名詞的屬性。例如銷售人員與基本工資。基本工資可以作為銷售人員的屬性。文中寫到提取這類屬性,可以通過分析模型中的聚合與二元關聯的關系。可以得到接下來這張圖:
?
2 領域建模與日常生活
學會領域建模,只對開發人員有幫助么?
其實不是的,領域建模,本質是工程的高度抽象。如果我們把生活當成一個項目來看待,那么我們也可以對生活進行領域建模。又或者,我們遇到了一些問題,或者想去做成一件事情,那在這過程中,領域建模的能力可以幫到我們什么?
以解決一個問題,我們需要考慮哪些因素?問題、目標、現狀、方案。
高度抽象出這四個模型,然后我們對其進行建模。如果方案可行,那么這個 問題-目標-現狀-方案 的領域模型可以叫做什么?
我們可以理解為這是我們的處事模型,或者稱之為原則。
軟件工程教會了我們工程化的思維,領域建模訓練了我們高度抽象的能力。
從大學畢業后,我懵懵懂懂感覺到了這些知識與技能對于我日常生活的幫助,也初步有了模型化的概念。以至于在畢業后一兩年,我和友人交談的時候,經常扯到模型這個詞語。直到后面,我看了Ray Dalio《Principles》(中文名《原則》)后才明白,原來這就是所謂的處事模型 ——— 原則。
通過領域建模,得到日常生活的原則,這對于我們有什么好處呢?
舉個例子,我們將人腦的記憶部分比喻成磁盤。你遇到了一個問題,解決了一個問題,你告訴自己重復的錯誤不能再犯,于是你把這件事情記錄了起來。過了一段時間,你遇到了一個類似的問題,又重復了上面的步驟,將這件事情記錄到了磁盤里。
這么做有什么不好的地方呢,隨著時間的推移,你的記憶里會塞滿了各種各樣實例化后的犯錯經歷,等你想回憶某一件事的時候,你需要到磁盤里去掃描得這個數據,那估計得費一陣子功夫。再加上人腦是有記憶曲線的,早期的犯錯經歷,可能很快就被數據淘汰掉了。
但是如果在早期就有了抽象的思維,你會發現隨著時間推移,你所需要建立的“原則”越來越少,已有的原則會越來越完善。
所以說學會領域建模,有助于提升自己的抽象能力。有助于自己,to be a better man。
總結
以上是生活随笔為你收集整理的蚂蚁金服对研发高要求的领域建模能力是指什么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学妹问H哥:你是如何平衡工作和生活的?
- 下一篇: 技术招聘已经变味了