为什么你应该关心领域模型?
**簡介:**領(lǐng)域模型是DDD的核心,更是業(yè)務(wù)的深入認(rèn)知
作者簡介:張剛,軟件工程博士,阿里云云效資深技術(shù)專家,ALPD方法學(xué)核心成員。
引言
領(lǐng)域模型是重要的概念。但是,真正了解并能熟練運(yùn)用它的人并不多。這實(shí)在是殊為可惜的一件事情。
軟件開發(fā)中的許多問題,例如需求難于溝通,軟件難以演化,都和領(lǐng)域模型緊密相關(guān)。更關(guān)鍵的是,掌握這個(gè)概念并不難。通過練習(xí),一個(gè)團(tuán)隊(duì)只需要一兩個(gè)小時(shí),就可以習(xí)慣領(lǐng)域模型的建模思路,并且開始從中受益。
那么,什么是領(lǐng)域模型?如何理解領(lǐng)域模型的本質(zhì)?為什么領(lǐng)域模型能給軟件開發(fā)帶來巨大幫助?如何表達(dá)它,如何應(yīng)用它?本文將依次展開這些概念。
什么是領(lǐng)域模型?
首先我們來看什么是領(lǐng)域模型。
領(lǐng)域模?型定義了領(lǐng)域內(nèi)的關(guān)鍵的概念以及這些概念之間的關(guān)系。
?
為什么要強(qiáng)調(diào)“領(lǐng)域內(nèi)”?是因?yàn)槟P?#xff08;或者說概念)只在它所處問題空間中才有意義。這分為兩種情況:
1)一個(gè)概念只在某個(gè)特定領(lǐng)域有意義。例如,“應(yīng)收賬款”,就只是在財(cái)務(wù)領(lǐng)域,更嚴(yán)格的說是會(huì)計(jì)領(lǐng)域才有意義。
2)一個(gè)概念必須通過領(lǐng)域限定,才有具體的意義。例如,“軌道”這個(gè)概念,它可能是天文學(xué)領(lǐng)域的行星運(yùn)動(dòng)軌道,也可能是鐵路領(lǐng)域的火車軌道,必須得先限定領(lǐng)域,這個(gè)概念才有真正的價(jià)值。
關(guān)鍵信息1:領(lǐng)域模型最重要的是概念,領(lǐng)域模型也被稱為概念模型。
雖然有人說“領(lǐng)域模型是領(lǐng)域內(nèi)的概念的可視化表示”,但是, “可視化”并不本質(zhì),雖然它也重要。相比較而言,“概念”才是根本。
關(guān)鍵信息2:“語言的邊界就是思想的邊界”—— 一個(gè)好的領(lǐng)域模型,必然承載了有用的知識(shí)。
對一個(gè)不熟悉特定領(lǐng)域的人來說,理解概念,往往是進(jìn)入一個(gè)領(lǐng)域最快的方式。例如,小時(shí)候的兒歌:太陽大,地球小,地球繞著太陽跑。地球大,月亮小,月亮繞著地球跑。它就可以認(rèn)為是一種概念模型的表達(dá)。在這個(gè)模型中,包括了3個(gè)概念實(shí)體:太陽,地球和月亮。而太陽和地球的關(guān)系是地球繞著太陽運(yùn)動(dòng),地球和月亮的關(guān)系是月亮繞著地球運(yùn)動(dòng)。用一張圖畫下來就是:
這張圖其實(shí)是UML的對象圖,當(dāng)然即使你不熟悉UML,就是作為線框圖,也能很容易理解。
同樣,在各種業(yè)務(wù)領(lǐng)域,都有自己的關(guān)鍵概念。這些概念的表達(dá)也不一定是圖。例如,剛才所講的會(huì)計(jì)領(lǐng)域,我們可以使用一張表來表達(dá)下列的幾個(gè)關(guān)鍵概念:
會(huì)計(jì)主體(本方)->對方 | |
應(yīng)收賬款 | 貨物已經(jīng)發(fā)給對方,但是尚未收到貨款 |
應(yīng)付賬款 | 已經(jīng)收到對方貨物,但是尚未支付貨款 |
預(yù)收賬款 | 已經(jīng)收到對方貨款,但是尚未發(fā)貨 |
預(yù)付賬款 | 已經(jīng)支付對方貨款,但是尚未收到貨物 |
通過這樣一張表格,相信即使對會(huì)計(jì)領(lǐng)域不甚了解對小伙伴,也能快速掌握相關(guān)的知識(shí)。如果我們更進(jìn)一步,能夠理解到,應(yīng)收和預(yù)付,本質(zhì)上是本方的債權(quán),而預(yù)收和應(yīng)付,本質(zhì)上是本方的債務(wù)。用一張圖表示就是:
在這里我們使用了UML類圖來表示。對于不熟悉UML的小伙伴,可能需要解釋一下三角形箭頭的意思,它代表“是一種”,例如,應(yīng)收賬款是一種債權(quán)。
更嚴(yán)格的,如果一筆應(yīng)收賬款的帳期已經(jīng)很長,例如5年,那么這種賬款有很大概率已經(jīng)收不回來了,所以需要計(jì)提壞賬。有一些通用的壞賬計(jì)提策略,例如:一年以內(nèi)5%,一到二年20%,二到三年50%,三年以上100%等。所以,面向剛才的應(yīng)收賬款,我們可以用下面的圖來表達(dá)這樣的概念:
圖是一種視圖,它不需要面面俱到。例如,本圖中,并沒有顯示一切和會(huì)計(jì)科目相關(guān)的信息,而只是集中于壞賬的計(jì)提。其中,我們在應(yīng)付賬款和壞賬之間引入了一個(gè)新的符號,認(rèn)識(shí)UML的小伙伴知道我們表達(dá)的是”應(yīng)?收賬款中包括壞賬“。圖中的帳期、金額等,我們成為“屬性”,用于詳細(xì)的說明應(yīng)收賬款、壞賬這些概念還包括哪些內(nèi)容。
?
由于領(lǐng)域模型本質(zhì)上傳遞的是概念,是知識(shí)性的信息,所以,對于軟件開發(fā)的場景來說,把這些知識(shí)顯式化,能快速對齊不同角色、不同參與方之間的概念,加速溝通,避免誤解。
?
領(lǐng)域模型是重要的業(yè)務(wù)資產(chǎn)
領(lǐng)域概念沉淀業(yè)務(wù)知識(shí),而且非常穩(wěn)定。
一家在某個(gè)領(lǐng)域深耕多年的企業(yè),和一個(gè)新入行的企業(yè),差別是什么?差距可能是多方面的,但是最大的差距應(yīng)該是“認(rèn)知”?!晕覀兂3?huì)看到,新入行的企業(yè)追趕深耕多年的企業(yè)的辦法,常常是去成熟的的企業(yè)高薪“挖角”。按道理說,挖來的這些人既不能把原公司的客戶帶來,也不可能把原公司的系統(tǒng)帶來,那么本質(zhì)上他們給新企業(yè)帶來了什么呢?他們對新公司最大的幫助,是對特定領(lǐng)域的認(rèn)知。在業(yè)務(wù)領(lǐng)域,認(rèn)知非常值錢,而且非常穩(wěn)定。我們也會(huì)看到,一些在某個(gè)領(lǐng)域建立了優(yōu)勢的企業(yè),特別是咨詢類企業(yè),單靠業(yè)務(wù)領(lǐng)域的咨詢,就能給企業(yè)帶來客觀的收入。如果有良好維護(hù)的領(lǐng)域模型,那么領(lǐng)域模型就是這些認(rèn)知沉淀的最佳位置所在。
更重要的是,盡管業(yè)務(wù)常新,但是領(lǐng)域模型卻相當(dāng)穩(wěn)定。我們以商品交易為例。我們知道買家、買家、商品、交易這些概念,都是商品交易領(lǐng)域的核心概念。這些概念并不會(huì)隨著業(yè)務(wù)的演進(jìn)發(fā)生劇烈的變化,無論是B2C業(yè)務(wù),C2C業(yè)務(wù),C2M業(yè)務(wù),拼團(tuán)業(yè)務(wù)還是秒殺業(yè)務(wù)。不同的業(yè)務(wù),體現(xiàn)的只是對這些業(yè)務(wù)概念的不同組織方式。當(dāng)然,真正的領(lǐng)域模型要遠(yuǎn)遠(yuǎn)比上述概念復(fù)雜的多。我們這里只是舉一個(gè)簡單的例子,說明領(lǐng)域概念的穩(wěn)定性。
領(lǐng)域模型的躍遷和生長
當(dāng)然,我們說領(lǐng)域模型穩(wěn)定,并不是說它一成不變。優(yōu)秀的領(lǐng)域模型都一定會(huì)持續(xù)生長,甚至有時(shí)候會(huì)發(fā)生本質(zhì)的躍遷。
一旦一個(gè)模型被推翻,我們會(huì)認(rèn)為,我們對某個(gè)領(lǐng)域的認(rèn)知,一定發(fā)生了非常本質(zhì)的躍遷。例如,前述的兒歌“太陽大,地球小,地球繞著太陽跑。地球大,月亮小,月亮繞著地球跑?!辈⒉皇且婚_始就是這樣認(rèn)知的。無論中外,在幾百年前,我們都曾經(jīng)認(rèn)為,地球是宇宙的中心,太陽、月亮都是繞著地球運(yùn)行的。那么,這個(gè)模型畫出來就是下面這個(gè)樣子:
地心說對象圖
地心說到日心說,是我們宇宙認(rèn)知到巨大進(jìn)步,以為日心說模型徹底否定了地心說模型。在軟件領(lǐng)域也是這樣。我曾經(jīng)經(jīng)歷過幾次領(lǐng)域模型躍遷的場景,每次都伴隨這業(yè)務(wù)認(rèn)知的巨大進(jìn)步。
當(dāng)然,在現(xiàn)實(shí)生活中,躍遷并不多見。更多的時(shí)候都是在原有的模型上穩(wěn)定發(fā)展,逐步增入各種新的概念和各種細(xì)節(jié)。模型的生長過程,本質(zhì)上也是業(yè)務(wù)能力積累的過程。
穩(wěn)定的領(lǐng)域模型帶來軟件的適應(yīng)性
需求是不穩(wěn)定性的,而領(lǐng)域模型是穩(wěn)定的,這啟發(fā)我們,如果以領(lǐng)域模型為中心去構(gòu)造軟件,那么我們就會(huì)構(gòu)造出很多穩(wěn)定的積木塊。新的需求,就可能通過這些穩(wěn)定的積木塊,通過不同的搭建方式,形成豐富多彩的應(yīng)用。在這種情況下,我們的軟件對于變化的適應(yīng)力最強(qiáng),開發(fā)成本最低。
領(lǐng)域模型存在于哪里
用類圖表示領(lǐng)域模型
UML類圖是表達(dá)領(lǐng)域模型的非常好的工具,雖然并不存在如何表達(dá)領(lǐng)域模型的標(biāo)準(zhǔn)。因?yàn)樵赨ML中,“類”并不簡單是軟件設(shè)計(jì)中的“類”,它代表的其實(shí)是“概念”,所以,把類圖用在領(lǐng)域模型的表達(dá)上,是非常恰切的。而且,UML已經(jīng)約定了概念和概念之間的關(guān)系,例如:類、屬性、關(guān)聯(lián)、關(guān)聯(lián)的多重性、泛化、聚合、組合、依賴等等。
對于不熟悉UML的人來說,使用UML也完全沒必要有什么心理負(fù)擔(dān)。UML是一個(gè)高度靈活的結(jié)構(gòu),它具有漸近的能力。你沒有必要掌握所有復(fù)雜的概念才開始工作,根據(jù)我的經(jīng)驗(yàn),只要一開始能把類(代表概念)、類的屬性和它們的關(guān)系描述出來,最多再知道多重性怎么表示,就足以應(yīng)付大多數(shù)的場景。
有些小伙伴有面向?qū)ο蟮慕?jīng)驗(yàn),在這里會(huì)糾結(jié)于要不要對“方法/操作”進(jìn)行建模。在“領(lǐng)域模型”是一種“業(yè)務(wù)概念”這個(gè)上下文中,方法是完全多余的東西,暫時(shí)不需要在這個(gè)階段進(jìn)行建模。我認(rèn)為在實(shí)現(xiàn)階段補(bǔ)足它們更合適。
在交流和文檔中使用領(lǐng)域模型
領(lǐng)域模型寫在紙上并不是最關(guān)鍵的。作為概念模型,它反映了這個(gè)領(lǐng)域的最重要的概念,也構(gòu)成了表達(dá)業(yè)務(wù)概念的詞匯。所以:
最好的領(lǐng)域模型,應(yīng)該時(shí)刻存在于團(tuán)隊(duì)成員的心中,存在于日常的交流活動(dòng)中。
?
為了做到這一點(diǎn),我對自己的團(tuán)隊(duì)和輔導(dǎo)過的團(tuán)隊(duì),都有一個(gè)要求,這個(gè)要求也被成為交流活動(dòng)中的“統(tǒng)一語言”:
任何在需求描述中出現(xiàn)的概念,都必須出現(xiàn)在領(lǐng)域模型中。如果需求描述中存在概念之間的關(guān)系,領(lǐng)域模型中也必須有這個(gè)關(guān)系
這個(gè)要求看似簡單,實(shí)際做到會(huì)比較困難。特別在剛開始的時(shí)候,團(tuán)隊(duì)成員可能并不適應(yīng)這種做法,常常就忘記了這個(gè)準(zhǔn)則,需要經(jīng)常糾正。但是一旦習(xí)慣,大家會(huì)發(fā)現(xiàn),在日常交流活動(dòng)中,因?yàn)樗械母拍疃家呀?jīng)顯式化,誤解大大減少,共識(shí)更容易達(dá)成,導(dǎo)致的后果就是最后團(tuán)隊(duì)成員,都會(huì)非常自覺的維護(hù)“統(tǒng)一語言”的做法。
出于同樣的原因,編寫文檔時(shí),使用領(lǐng)域模型作為統(tǒng)一語言也成了一個(gè)非常自然的結(jié)果。
在代碼中使用領(lǐng)域模型
由于領(lǐng)域模型已經(jīng)被顯式化,所以如果能夠在代碼中使用領(lǐng)域模型,那么代碼就會(huì)獲得更好的易讀性。由于領(lǐng)域模型和代碼對應(yīng)的更加一致,那么在領(lǐng)域模型發(fā)生演進(jìn)時(shí),代碼就會(huì)變得更容易演進(jìn)。在這方面,領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)給出了一組完備的模式,可以幫助架構(gòu)師和開發(fā)人員自然地把領(lǐng)域模型轉(zhuǎn)化為代碼。本文中我們并不準(zhǔn)備展開這些模式。在此,暫時(shí)先請讀者們記住下面的結(jié)論,后面會(huì)有更深入的討論:
代碼和問題域之間的表示差距應(yīng)該盡量縮小,領(lǐng)域模型是連接現(xiàn)實(shí)世界和數(shù)字世界的最佳橋梁。使用領(lǐng)域模型作為代碼中的業(yè)務(wù)概念的基本表達(dá)元素,可以大幅提升代碼的易讀性,也可以更好的支持業(yè)務(wù)的演進(jìn)。
領(lǐng)域模型來自哪里
領(lǐng)域模型反映了關(guān)鍵的業(yè)務(wù)認(rèn)知,但是認(rèn)知并不會(huì)憑空建立。能夠一上來就洞悉一切本質(zhì)的,要么是這個(gè)人是天才,要么說明這個(gè)領(lǐng)域已經(jīng)是一個(gè)非常成熟的領(lǐng)域,已經(jīng)無需探索和發(fā)現(xiàn)。
大多數(shù)時(shí)候,認(rèn)知都來自于業(yè)務(wù)場景的啟發(fā)。所以,領(lǐng)域模型建立的過程,往往是伴隨著需求分析同步產(chǎn)生的。
我畫了下面這張圖,來說明領(lǐng)域模型和業(yè)務(wù)場景之間的關(guān)系:
也就是說,領(lǐng)域模型是在業(yè)務(wù)場景的激勵(lì)下逐漸完善的。而且,反過來因?yàn)閷︻I(lǐng)域的認(rèn)知更加深刻,領(lǐng)域模型還有助于新的業(yè)務(wù)場景的發(fā)現(xiàn)。
探索和發(fā)現(xiàn)最好不要一個(gè)人獨(dú)自進(jìn)行。更多地時(shí)候,應(yīng)該盡量進(jìn)行集體建模。集體建模不僅僅利于探索和發(fā)現(xiàn),而且它也有助于達(dá)成對于關(guān)鍵業(yè)務(wù)概念的共識(shí)。
集體建模的最好工具并不是UML的電子化工具,使用白板,在開放空間中的討論,往往能夠收到最好的效果。
由于領(lǐng)域模型表達(dá)的是概念,所以對于概念及時(shí)地分解和抽象,是領(lǐng)域建模的基本功。當(dāng)然,現(xiàn)實(shí)中受過嚴(yán)格的分解和抽象訓(xùn)練的人并不多,特別是很多業(yè)務(wù)人員往往都缺乏這方面的能力。我在實(shí)際工作中,觀察到具有面向?qū)ο蠼?jīng)驗(yàn)的開發(fā)人員,經(jīng)過一定時(shí)間的練習(xí),可以很快掌握這方面的技能。所以,如果有一些具有經(jīng)驗(yàn)的開發(fā)人員參與建模,往往可以獲得質(zhì)量更高的模型。
常見誤區(qū)
領(lǐng)域模型的概念產(chǎn)生于90年代的面向?qū)ο笊鐓^(qū)。在那個(gè)時(shí)候,業(yè)務(wù)變化還不像今天這樣頻繁,迭代的思想也還沒有完全成熟,業(yè)務(wù)人員和技術(shù)人員也沒有像今天這樣密集的交流,所以,無論是從參考書上,還是實(shí)踐上,領(lǐng)域模型的概念都難免留下早年做法的影響。其中,有若干誤區(qū),在實(shí)踐中是應(yīng)該盡量避免的:
誤區(qū)1:?從開發(fā)視角進(jìn)行領(lǐng)域模型的建模
常常有技術(shù)人員問:“領(lǐng)域模型和ER圖有什么關(guān)系?” 對這個(gè)問題最直接的回答就是:“沒有關(guān)系”。固然,我肯定知道在有了領(lǐng)域模型之后,設(shè)計(jì)ER圖會(huì)更簡單,或者對于一個(gè)還缺乏領(lǐng)域模型的遺留系統(tǒng),研究數(shù)據(jù)庫結(jié)構(gòu)可以帶來有效的輸入,但是它們的立足點(diǎn)是完全不一樣的。
領(lǐng)域模型一定要從業(yè)務(wù)視角去看,因?yàn)轭I(lǐng)域模型反映的是業(yè)務(wù)認(rèn)知。一旦在領(lǐng)域模型中摻雜了技術(shù)的概念,不僅僅是因?yàn)樗粔蚣兇?#xff0c;更重要的是它已經(jīng)堵死了從業(yè)務(wù)視角對領(lǐng)域模型進(jìn)行演進(jìn)和糾正的機(jī)會(huì)。因?yàn)闆]有軟件背景的業(yè)務(wù)人員,是不可能去看一個(gè)充斥著技術(shù)概念的模型的。統(tǒng)一語言無法建立,領(lǐng)域模型帶來的價(jià)值就已經(jīng)損失了一大部分。此外,從開發(fā)視角進(jìn)行建模,往往還會(huì)忽視業(yè)務(wù)人員的參與。而實(shí)踐一再表明,資深的業(yè)務(wù)人員在領(lǐng)域建模時(shí),往往能提出深入的洞察。所以,從開發(fā)視角對領(lǐng)域模型進(jìn)行建模絕對不可取。
誤區(qū)2: 建立龐大的領(lǐng)域模型
當(dāng)我們說“領(lǐng)域”的時(shí)候,并沒有限定一個(gè)“領(lǐng)域”應(yīng)該有多大。究竟是“航空”作為一個(gè)領(lǐng)域,還是“航空”中的“訂票”是一個(gè)領(lǐng)域?
當(dāng)你考慮到“領(lǐng)域的核心是認(rèn)知”,這個(gè)答案就變得非常清楚了。領(lǐng)域越大,越不利于建立認(rèn)知和共識(shí)。我們應(yīng)該這問題域,把大的領(lǐng)域劃分為小的領(lǐng)域,然后逐個(gè)建立這些小的領(lǐng)域的領(lǐng)域模型。那種整整一面墻的領(lǐng)域模型,往往都是不可取的。?
誤區(qū)3: 重文檔,輕交流和共識(shí)
領(lǐng)域模型的核心在于建立共同的共識(shí),所以,如果只是把領(lǐng)域模型作為一種“制品”,作為某個(gè)階段的“輸出”,這是非常不合適的。領(lǐng)域模型需要作為交流工具?!敖y(tǒng)一語言”是避免該誤區(qū)的重要方法。
誤區(qū)4: 不把領(lǐng)域模型顯式化
很多人認(rèn)為自己是有“認(rèn)知”的,甚至是有“領(lǐng)域模型”的,但是,如果你問他們模型在哪里,這些要么就是在某個(gè)項(xiàng)目曾經(jīng)有過一些討論,但是現(xiàn)在已經(jīng)不知所蹤,要么就是雖然文檔還在,但是團(tuán)隊(duì)的概念表達(dá)依舊混亂。沒有顯式化,沒有把領(lǐng)域模型寫下來,沒有形成團(tuán)隊(duì)口口相傳的知識(shí),那么這種模型,并不真正存在。除了“統(tǒng)一語言”,我們還有一個(gè)非常簡便的檢驗(yàn)方法,就是看這個(gè)團(tuán)隊(duì)如何給新人介紹自己的系統(tǒng)。因?yàn)轭I(lǐng)域模型反映了基本的業(yè)務(wù)概念,是一個(gè)非常好的新人培養(yǎng)工具,但凡真正有“領(lǐng)域模型”的組織,是不可能不把領(lǐng)域模型拿出來做介紹的。
總結(jié)
本文我們主要介紹了領(lǐng)域模型的基本概念及重要度,領(lǐng)域模型對于“統(tǒng)一語言”的價(jià)值以及領(lǐng)域模型應(yīng)用的常見誤區(qū)。
總結(jié)一下要點(diǎn):
- 領(lǐng)域模型的本質(zhì)是概念和認(rèn)知,它定義了領(lǐng)域內(nèi)的關(guān)鍵概念以及這些概念之間的關(guān)系
- 相對于業(yè)務(wù)的多變,領(lǐng)域模型相對穩(wěn)定,優(yōu)質(zhì)的領(lǐng)域模型可以低成本的支持業(yè)務(wù),領(lǐng)域模型也是統(tǒng)一語言的基礎(chǔ),能有效提升溝通效率
- 領(lǐng)域模型來自于業(yè)務(wù)滋養(yǎng),領(lǐng)域模型生長的過程,也是業(yè)務(wù)認(rèn)知建立的過程,協(xié)作建模是更有效的建模方法
在你的團(tuán)隊(duì)中,有顯式的領(lǐng)域模型和共同的業(yè)務(wù)認(rèn)知嗎?它在指導(dǎo)日常的交流和開發(fā)工作嗎?如果還沒有,讓我們開始吧。
原文鏈接:https://developer.aliyun.com/article/784470?
**版權(quán)聲明:**本文內(nèi)容由阿里云實(shí)名注冊用戶自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,阿里云開發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。具體規(guī)則請查看《阿里云開發(fā)者社區(qū)用戶服務(wù)協(xié)議》和《阿里云開發(fā)者社區(qū)知識(shí)產(chǎn)權(quán)保護(hù)指引》。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫侵權(quán)投訴表單進(jìn)行舉報(bào),一經(jīng)查實(shí),本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。
總結(jié)
以上是生活随笔為你收集整理的为什么你应该关心领域模型?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何成为云原生时代的卓越架构师?
- 下一篇: 如何评估Serverless服务能力,这