爲何你應該關心領域模型?

簡介:領域模型是DDD的核心,更是業務的深刻認知

做者簡介:張剛,軟件工程博士,阿里云云效資深技術專家,ALPD方法學核心成員。數據庫

讀者福利:前往:架構

https://developer.aliyun.com/topic/course/alpd工具

免費領取阿里爆款架構師課程《DDD高手進階12講》(原價98元)。學習

引言

領域模型是重要的概念。可是,真正瞭解並能熟練運用它的人並很少。這實在是殊爲惋惜的一件事情。阿里雲

軟件開發中的許多問題,例如需求難於溝通,軟件難以演化,都和領域模型緊密相關。更關鍵的是,掌握這個概念並不難。經過練習,一個團隊只須要一兩個小時,就能夠習慣領域模型的建模思路,而且開始從中受益。spa

那麼,什麼是領域模型?如何理解領域模型的本質?爲何領域模型能給軟件開發帶來巨大幫助?如何表達它,如何應用它?本文將依次展開這些概念。設計

什麼是領域模型?

首先咱們來看什麼是領域模型。對象

領域模​型定義了領域內的關鍵的概念以及這些概念之間的關係。圖片

爲何要強調「領域內」?是由於模型(或者說概念)只在它所處問題空間中才有意義。這分爲兩種狀況:開發

1)一個概念只在某個特定領域有意義。例如,「應收帳款」,就只是在財務領域,更嚴格的說是會計領域纔有意義。

2)一個概念必須經過領域限定,纔有具體的意義。例如,「軌道」這個概念,它多是天文學領域的行星運動軌道,也多是鐵路領域的火車軌道,必須得先限定領域,這個概念纔有真正的價值。

關鍵信息1:領域模型最重要的是概念,領域模型也被稱爲概念模型。

雖然有人說「領域模型是領域內的概念的可視化表示」,可是, 「可視化」並不本質,雖然它也重要。相比較而言,「概念」纔是根本。

關鍵信息2:「語言的邊界就是思想的邊界」—— 一個好的領域模型,必然承載了有用的知識。

對一個不熟悉特定領域的人來講,理解概念,每每是進入一個領域最快的方式。例如,小時候的兒歌:太陽大,地球小,地球繞着太陽跑。地球大,月亮小,月亮繞着地球跑。它就能夠認爲是一種概念模型的表達。在這個模型中,包括了3個概念實體:太陽,地球和月亮。而太陽和地球的關係是地球繞着太陽運動,地球和月亮的關係是月亮繞着地球運動。用一張圖畫下來就是:

圖片 1.png

這張圖實際上是UML的對象圖,固然即便你不熟悉UML,就是做爲線框圖,也能很容易理解。

一樣,在各類業務領域,都有本身的關鍵概念。這些概念的表達也不必定是圖。例如,剛纔所講的會計領域,咱們可使用一張表來表達下列的幾個關鍵概念:

<span>會計主體(本方)->對方</span>
<span>應收帳款</span> <span>貨物已經發給對方,可是還沒有收到貨款</span>
<span>應付帳款</span> <span>已經收到對方貨物,可是還沒有支付貨款</span>
<span>預收帳款</span> <span>已經收到對方貨款,可是還沒有發貨</span>
<span>預付帳款</span> <span>已經支付對方貨款,可是還沒有收到貨物</span>
經過這樣一張表格,相信即便對會計領域不甚瞭解對小夥伴,也能快速掌握相關的知識。若是咱們更進一步,可以理解到,應收和預付,本質上是本方的債權,而預收和應付,本質上是本方的債務。用一張圖表示就是: 圖片 2.png 在這裏咱們使用了UML類圖來表示。對於不熟悉UML的小夥伴,可能須要解釋一下三角形箭頭的意思,它表明「是一種」,例如,應收帳款是一種債權。 更嚴格的,若是一筆應收帳款的賬期已經很長,例如5年,那麼這種帳款有很大機率已經收不回來了,因此須要計提壞帳。有一些通用的壞帳計提策略,例如:一年之內5%,一到二年20%,二到三年50%,三年以上100%等。因此,面向剛纔的應收帳款,咱們能夠用下面的圖來表達這樣的概念: 圖片 3.png 圖是一種視圖,它不須要面面俱到。例如,本圖中,並無顯示一切和會計科目相關的信息,而只是集中於壞帳的計提。其中,咱們在應付帳款和壞帳之間引入了一個新的符號,認識UML的小夥伴知道咱們表達的是」應​收帳款中包括壞帳「。圖中的賬期、金額等,咱們成爲「屬性」,用於詳細的說明應收帳款、壞帳這些概念還包括哪些內容。 ​ 因爲領域模型本質上傳遞的是概念,是知識性的信息,因此,對於軟件開發的場景來講,把這些知識顯式化,能快速對齊不一樣角色、不一樣參與方之間的概念,加速溝通,避免誤解。 ​ # 領域模型是重要的業務資產 ## 領域概念沉澱業務知識,並且很是穩定。 一家在某個領域深耕多年的企業,和一個新入行的企業,差異是什麼?差距多是多方面的,可是最大的差距應該是「認知」。——因此咱們經常會看到,新入行的企業追趕深耕多年的企業的辦法,經常是去成熟的的企業高薪「挖角」。按道理說,挖來的這些人既不能把原公司的客戶帶來,也不可能把原公司的系統帶來,那麼本質上他們給新企業帶來了什麼呢?他們對新公司最大的幫助,是對特定領域的認知。在業務領域,認知很是值錢,並且很是穩定。咱們也會看到,一些在某個領域創建了優點的企業,特別是諮詢類企業,單靠業務領域的諮詢,就能給企業帶來客觀的收入。若是有良好維護的領域模型,那麼領域模型就是這些認知沉澱的最佳位置所在。 更重要的是,儘管業務常新,可是領域模型卻至關穩定。咱們以商品交易爲例。咱們知道買家、買家、商品、交易這些概念,都是商品交易領域的核心概念。這些概念並不會隨着業務的演進發生劇烈的變化,不管是B2C業務,C2C業務,C2M業務,拼團業務仍是秒殺業務。不一樣的業務,體現的只是對這些業務概念的不一樣組織方式。固然,真正的領域模型要遠遠比上述概念複雜的多。咱們這裏只是舉一個簡單的例子,說明領域概念的穩定性。 ## 領域模型的躍遷和生長 固然,咱們說領域模型穩定,並非說它一成不變。優秀的領域模型都必定會持續生長,甚至有時候會發生本質的躍遷。 一旦一個模型被推翻,咱們會認爲,咱們對某個領域的認知,必定發生了很是本質的躍遷。例如,前述的兒歌「太陽大,地球小,地球繞着太陽跑。地球大,月亮小,月亮繞着地球跑。」並非一開始就是這樣認知的。不管中外,在幾百年前,咱們都曾經認爲,地球是宇宙的中心,太陽、月亮都是繞着地球運行的。那麼,這個模型畫出來就是下面這個樣子: 圖片 4.png 地心說對象圖 地心說到日心說,是咱們宇宙認知到巨大進步,覺得日心說模型完全否認了地心說模型。在軟件領域也是這樣。我曾經經歷過幾回領域模型躍遷的場景,每次都伴隨這業務認知的巨大進步。 固然,在現實生活中,躍遷並很少見。更多的時候都是在原有的模型上穩定發展,逐步增入各類新的概念和各類細節。模型的生長過程,本質上也是業務能力積累的過程。 ## 穩定的領域模型帶來軟件的適應性 需求是不穩定性的,而領域模型是穩定的,這啓發咱們,若是以領域模型爲中心去構造軟件,那麼咱們就會構造出不少穩定的積木塊。新的需求,就可能經過這些穩定的積木塊,經過不一樣的搭建方式,造成豐富多彩的應用。在這種狀況下,咱們的軟件對於變化的適應力最強,開發成本最低。 # 領域模型存在於哪裏 ## 用類圖表示領域模型 UML類圖是表達領域模型的很是好的工具,雖然並不存在如何表達領域模型的標準。由於在UML中,「類」並不簡單是軟件設計中的「類」,它表明的實際上是「概念」,因此,把類圖用在領域模型的表達上,是很是恰切的。並且,UML已經約定了概念和概念之間的關係,例如:類、屬性、關聯、關聯的多重性、泛化、聚合、組合、依賴等等。 對於不熟悉UML的人來講,使用UML也徹底不必有什麼心理負擔。UML是一個高度靈活的結構,它具備漸近的能力。你沒有必要掌握全部複雜的概念纔開始工做,根據個人經驗,只要一開始能把類(表明概念)、類的屬性和它們的關係描述出來,最多再知道多重性怎麼表示,就足以應付大多數的場景。 有些小夥伴有面向對象的經驗,在這裏會糾結於要不要對「方法/操做」進行建模。在「領域模型」是一種「業務概念」這個上下文中,方法是徹底多餘的東西,暫時不須要在這個階段進行建模。我認爲在實現階段補足它們更合適。 ## 在交流和文檔中使用領域模型 領域模型寫在紙上並非最關鍵的。做爲概念模型,它反映了這個領域的最重要的概念,也構成了表達業務概念的詞彙。因此: 最好的領域模型,應該時刻存在於團隊成員的心中,存在於平常的交流活動中。 ​ 爲了作到這一點,我對本身的團隊和輔導過的團隊,都有一個要求,這個要求也被成爲交流活動中的「統一語言」: 任何在需求描述中出現的概念,都必須出如今領域模型中。若是需求描述中存在概念之間的關係,領域模型中也必須有這個關係 這個要求看似簡單,實際作到會比較困難。特別在剛開始的時候,團隊成員可能並不適應這種作法,經常就忘記了這個準則,須要常常糾正。可是一旦習慣,你們會發現,在平常交流活動中,由於全部的概念都已經顯式化,誤解大大減小,共識更容易達成,致使的後果就是最後團隊成員,都會很是自覺的維護「統一語言」的作法。 出於一樣的緣由,編寫文檔時,使用領域模型做爲統一語言也成了一個很是天然的結果。 ## 在代碼中使用領域模型 因爲領域模型已經被顯式化,因此若是可以在代碼中使用領域模型,那麼代碼就會得到更好的易讀性。因爲領域模型和代碼對應的更加一致,那麼在領域模型發生演進時,代碼就會變得更容易演進。在這方面,領域驅動設計給出了一組完備的模式,能夠幫助架構師和開發人員天然地把領域模型轉化爲代碼。本文中咱們並不許備展開這些模式。在此,暫時先請讀者們記住下面的結論,後面會有更深刻的討論: 代碼和問題域之間的表示差距應該儘可能縮小,領域模型是鏈接現實世界和數字世界的最佳橋樑。使用領域模型做爲代碼中的業務概念的基本表達元素,能夠大幅提高代碼的易讀性,也能夠更好的支持業務的演進。 # 領域模型來自哪裏 領域模型反映了關鍵的業務認知,可是認知並不會憑空創建。可以一上來就洞悉一切本質的,要麼是這我的是天才,要麼說明這個領域已是一個很是成熟的領域,已經無需探索和發現。 大多數時候,認知都來自於業務場景的啓發。因此,領域模型創建的過程,每每是伴隨着需求分析同步產生的。 我畫了下面這張圖,來講明領域模型和業務場景之間的關係: 圖片 5.png 也就是說,領域模型是在業務場景的激勵下逐漸完善的。並且,反過來由於對領域的認知更加深入,領域模型還有助於新的業務場景的發現。 探索和發現最好不要一我的獨自進行。更多地時候,應該儘可能進行集體建模。集體建模不只僅利於探索和發現,並且它也有助於達成對於關鍵業務概念的共識。 集體建模的最好工具並非UML的電子化工具,使用白板,在開放空間中的討論,每每可以收到最好的效果。 因爲領域模型表達的是概念,因此對於概念及時地分解和抽象,是領域建模的基本功。固然,現實中受過嚴格的分解和抽象訓練的人並很少,特別是不少業務人員每每都缺少這方面的能力。我在實際工做中,觀察到具備面向對象經驗的開發人員,通過必定時間的練習,能夠很快掌握這方面的技能。因此,若是有一些具備經驗的開發人員參與建模,每每能夠得到質量更高的模型。 # 常見誤區 領域模型的概念產生於90年代的面向對象社區。在那個時候,業務變化還不像今天這樣頻繁,迭代的思想也尚未徹底成熟,業務人員和技術人員也沒有像今天這樣密集的交流,因此,不管是從參考書上,仍是實踐上,領域模型的概念都不免留下早年作法的影響。其中,有若干誤區,在實踐中是應該儘可能避免的: ## 誤區1:  從開發視角進行領域模型的建模 經常有技術人員問:「領域模型和ER圖有什麼關係?」 對這個問題最直接的回答就是:「沒有關係」。當然,我確定知道在有了領域模型以後,設計ER圖會更簡單,或者對於一個還缺少領域模型的遺留系統,研究數據庫結構能夠帶來有效的輸入,可是它們的立足點是徹底不同的。 領域模型必定要從業務視角去看,由於領域模型反映的是業務認知。一旦在領域模型中摻雜了技術的概念,不只僅是由於它不夠純粹,更重要的是它已經堵死了從業務視角對領域模型進行演進和糾正的機會。由於沒有軟件背景的業務人員,是不可能去看一個充斥着技術概念的模型的。統一語言沒法創建,領域模型帶來的價值就已經損失了一大部分。此外,從開發視角進行建模,每每還會忽視業務人員的參與。而實踐一再代表,資深的業務人員在領域建模時,每每能提出深刻的洞察。因此,從開發視角對領域模型進行建模絕對不可取。 ## 誤區2: 創建龐大的領域模型 當咱們說「領域」的時候,並無限定一個「領域」應該有多大。到底是「航空」做爲一個領域,仍是「航空」中的「訂票」是一個領域? 當你考慮到「領域的核心是認知」,這個答案就變得很是清楚了。領域越大,越不利於創建認知和共識。咱們應該這問題域,把大的領域劃分爲小的領域,而後逐個創建這些小的領域的領域模型。那種整整一面牆的領域模型,每每都是不可取的。 ## 誤區3: 重文檔,輕交流和共識 領域模型的核心在於創建共同的共識,因此,若是隻是把領域模型做爲一種「製品」,做爲某個階段的「輸出」,這是很是不合適的。領域模型須要做爲交流工具。「統一語言」是避免該誤區的重要方法。 ## 誤區4: 不把領域模型顯式化 不少人認爲本身是有「認知」的,甚至是有「領域模型」的,可是,若是你問他們模型在哪裏,這些要麼就是在某個項目曾經有過一些討論,可是如今已經不知所蹤,要麼就是雖然文檔還在,可是團隊的概念表達依舊混亂。沒有顯式化,沒有把領域模型寫下來,沒有造成團隊口口相傳的知識,那麼這種模型,並不真正存在。除了「統一語言」,咱們還有一個很是簡便的檢驗方法,就是看這個團隊如何給新人介紹本身的系統。由於領域模型反映了基本的業務概念,是一個很是好的新人培養工具,但凡真正有「領域模型」的組織,是不可能不把領域模型拿出來作介紹的。 # 總結 本文咱們主要介紹了領域模型的基本概念及重要度,領域模型對於「統一語言」的價值以及領域模型應用的常見誤區。 總結一下要點: * 領域模型的本質是概念和認知,它定義了領域內的關鍵概念以及這些概念之間的關係 * 相對於業務的多變,領域模型相對穩定,優質的領域模型能夠低成本的支持業務,領域模型也是統一語言的基礎,能有效提高溝通效率 * 領域模型來自於業務滋養,領域模型生長的過程,也是業務認知創建的過程,協做建模是更有效的建模方法 在你的團隊中,有顯式的領域模型和共同的業務認知嗎?它在指導平常的交流和開發工做嗎?若是尚未,讓咱們開始吧。 * 課程推薦:《DDD高手進階12講》 本文內容源自阿里云云效推出的《ALPD雲架構師系列——DDD高手進階12講》。這是一門阿里內部的爆款課程,得到數千阿里工程師口碑推薦,值得每位開發者反覆學習。 或PC端前往以下連接獲取課程,免費領取阿里爆款架構師課程《DDD高手進階12講》(原價98元) https://developer.aliyun.com/topic/course/alpd > 本文內容由阿里雲實名註冊用戶自發貢獻,版權歸原做者全部,阿里雲開發者社區不擁有其著做權,亦不承擔相應法律責任。具體規則請查看《阿里雲開發者社區用戶服務協議》和《阿里雲開發者社區知識產權保護指引》。若是您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將馬上刪除涉嫌侵權內容。