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