DDD 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)學(xué)習(xí)(一)- 領(lǐng)域模型和統(tǒng)一語言

1. DDD是什么莺掠?解決什么問題?

1.1 軟件開發(fā)的困境

  • “隨著業(yè)務(wù)的擴(kuò)展,軟件開發(fā)投資越來越大” 團(tuán)隊(duì)的規(guī)模也開始變得越來越大战秋,軟件系統(tǒng)的投資和維護(hù)的成本變得越來越高。
  • “業(yè)務(wù)人員不懂架構(gòu)讨韭,架構(gòu)師不懂代碼脂信,開發(fā)人員不不懂業(yè)務(wù)模型” 當(dāng)團(tuán)隊(duì)中的關(guān)鍵角色誰也不懂誰的時(shí)候,問題來了透硝。狰闪。。
  • “重構(gòu)是好的濒生,但什么時(shí)候要重構(gòu)埋泵?重構(gòu)到什么樣的架構(gòu)就是夠?的了?” 每個(gè)有追求的團(tuán)隊(duì)都在做重構(gòu)罪治,但管理者更關(guān)心丽声,什么時(shí)間必須要重構(gòu)?重構(gòu)的目標(biāo)在哪觉义?

1.2 DDD的來源及簡介

?? 2004年Eric Evans 發(fā)表Domain-Driven Design –Tackling Complexity in the Heart of Software (領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))恒序,簡稱DDD,DDD是一套綜合軟件系統(tǒng)分析和設(shè)計(jì)的面向?qū)ο蠼7椒ā?br> ?? Eric的著名書籍《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》的副標(biāo)題是“軟件核心復(fù)雜性的應(yīng)對(duì)之道”谁撼,這個(gè)其實(shí)點(diǎn)出了DDD的來源和目標(biāo)歧胁,很多因素會(huì)使軟件的開發(fā)復(fù)雜化滋饲。軟件是從現(xiàn)實(shí)世界到數(shù)字世界的一種建模和映射,軟件復(fù)雜性的根本原因還是業(yè)務(wù)本身復(fù)雜性喊巍,軟件開發(fā)者無法回避這種復(fù)雜性屠缭,所能做的是去控制這種復(fù)雜性。
怎樣才能讓軟件和領(lǐng)域和諧相處呢崭参?最佳方式是讓軟件成為領(lǐng)域的一個(gè)映射呵曹。軟件需要包含領(lǐng)域里重要的核心概念和元素,并精確實(shí)現(xiàn)它們之間的關(guān)系何暮。也就是說奄喂,軟件需要對(duì)領(lǐng)域進(jìn)行建模。
?? 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)分為兩個(gè)階段:以一種領(lǐng)域?qū)<液M荨⒃O(shè)計(jì)人員跨新、開發(fā)人員都能理解的通用語言作為相互交流的工具,在交流的過程中發(fā)現(xiàn)領(lǐng)域概念坏逢,然后將這些概念設(shè)計(jì)成一個(gè)領(lǐng)域模型;第二個(gè)階段是由領(lǐng)域模型驅(qū)動(dòng)軟件設(shè)計(jì)域帐,用代碼來實(shí)現(xiàn)該領(lǐng)域模型。
?? 從DDD提出到開始流行是整,感覺經(jīng)過了10年左右的時(shí)間肖揣,巧的是XP和敏捷從提出到流行也差不多10年左右的時(shí)間「∪耄可見一套方法論從出現(xiàn)到成熟確實(shí)是有一定規(guī)律并需要成長時(shí)間的龙优。
?? 按Martin Fowler在PoEAA一書中給了一個(gè)圖。說明當(dāng)軟件在開發(fā)初期事秀,以數(shù)據(jù)驅(qū)動(dòng)的架構(gòu)方式非常容易上手彤断,但是隨著業(yè)務(wù)的增長和項(xiàng)目的推進(jìn),軟件開發(fā)和維護(hù)難度急劇升高秽晚。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)則在項(xiàng)目初期就處在一個(gè)比較難以上手的位置瓦糟,但是隨著業(yè)務(wù)的增長和項(xiàng)目的推進(jìn),軟件開發(fā)和維護(hù)難度平滑上升赴蝇。

Adapted from Martin Fowler's PoEAA

2. 模型和建模

2.1 什么是模型

  1. 模型是對(duì)客觀世界事物的一種抽象和簡化菩浙。
  2. 它是從某個(gè)角度反映人對(duì)客觀世界事物的一種認(rèn)識(shí)。
  3. 它用于對(duì)事物的本質(zhì)進(jìn)行深入細(xì)致的研究句伶。

2.2 模型的例子

2.2.1 地圖的例子

?? 地圖就是一種典型的模型【Ⅱ撸現(xiàn)實(shí)世界的地理信息往往很復(fù)雜,一個(gè)地理位置上會(huì)包括非常多的信息考余,例如有位置信息先嬉,地形,氣候等信息楚堤,也有城市疫蔓,道路含懊,綠化,管網(wǎng)衅胀,建筑等這些城市建設(shè)信息岔乔,還可能會(huì)有擁堵情況,商場(chǎng)滚躯,文化等各種附加于地理信息的各種信息在里面雏门。如何表達(dá)一個(gè)地圖信息其實(shí)并不容易,如何表達(dá)一個(gè)地圖信息是一件非常復(fù)雜的事情掸掏。
?? 我們常見的地圖茁影,一般都會(huì)縮小尺寸,忽略很多細(xì)節(jié)丧凤,分不同類型的地圖募闲,現(xiàn)在還有圖層的方式來表達(dá)不同地理信息。地圖其實(shí)就是一種模型息裸,而且地圖很多建模方式在軟件設(shè)計(jì)中也能找到映射蝇更。
?? 看兩個(gè)地圖例子沪编,建模從古至今就存在呼盆,而且隨著人們認(rèn)知水平和建模能力還會(huì)不斷的演進(jìn)。


圖一蚁廓、 古代天下地圖

圖二访圃、 百度地圖例子

?? 回到軟件研發(fā)的話題,軟件的研發(fā)也是一種建模的過程相嵌,傳統(tǒng)的方法中腿时,從問題空間到解決方案的空間,會(huì)經(jīng)過需求采集和分析饭宾,概要設(shè)計(jì)批糟,詳細(xì)設(shè)計(jì)再到編碼的過程。正如我們國家“系統(tǒng)分析師” 和“系統(tǒng)設(shè)計(jì)師” 兩種職稱考試一樣看铆,系統(tǒng)分析和系統(tǒng)設(shè)計(jì)是分離的徽鼎,“系統(tǒng)分析師” -BA屬于業(yè)務(wù)專家,“系統(tǒng)設(shè)計(jì)師”-SA是系統(tǒng)專家弹惦。隨著信息不斷傳遞的過程否淤,信息也在不斷的失真,導(dǎo)致可能到了最后交付階段才發(fā)現(xiàn)很多功能不是客戶想要的棠隐,或者客戶需求變化太快石抡,軟件的變更也不能快速跟隨需求變化。
?? 再舉一個(gè)常見的例子:一個(gè)函數(shù)寫了幾千行助泽,里面的if-else寫了一大堆啰扛,計(jì)算各種業(yè)務(wù)規(guī)則嚎京。另一個(gè)人接手之后,分析了好幾個(gè)月隐解,才把業(yè)務(wù)邏輯徹底理清楚挖藏。從表面來看,這是代碼寫的不規(guī)范厢漩,要重構(gòu)膜眠,把一個(gè)幾千行的函數(shù)拆成一個(gè)個(gè)小的函數(shù)。從根本上來講溜嗜,就是“重要邏輯”隱藏在代碼里面宵膨,沒有“顯性”的表達(dá)出來。這里可以引用一個(gè)觀點(diǎn):建模的本質(zhì)就是把“重要的東西進(jìn)行顯性化炸宵,并進(jìn)而把這些顯性化的構(gòu)造塊辟躏,互相串聯(lián)起來,組成一個(gè)體系“土全。
?? DDD通過建立一個(gè)業(yè)務(wù)域到軟件域的通用模型捎琐,把問題空間同解決方案空間聯(lián)系在一起,真正把領(lǐng)域的知識(shí)挖掘出來裹匙,讓領(lǐng)域?qū)<铱梢匀ヲ?qū)動(dòng)軟件的實(shí)現(xiàn)瑞凑。

3. 統(tǒng)一語言(UBIQUITOUS LANGUAGE)

?? 解決問題首先要從理解問題入手,很多事情的難點(diǎn)不在于解決問題概页,而在于認(rèn)知問題籽御。關(guān)于統(tǒng)一語言必要性,有一個(gè)經(jīng)典的通天塔故事惰匙,人類想建一座通天塔技掏,進(jìn)度很快,上帝害怕了项鬼,于是上帝讓建造者說不通的語言哑梳,這樣通天塔就再也沒有能建起來了。統(tǒng)一語言是一件事情能順利開展的基礎(chǔ)绘盟。
?? 由于語言上存在鴻溝鸠真,領(lǐng)域?qū)<覀冎荒苣:孛枋鏊麄兿胍臇|西,開發(fā)人員雖然努力去理解一個(gè)自己不熟悉的領(lǐng)域但也只能形成模糊的認(rèn)識(shí)奥此,結(jié)果就是各說各的話弧哎,或者都是一知半解,最后到上線前才會(huì)發(fā)現(xiàn)漏了這個(gè)漏了那個(gè)稚虎。
?? 通用語言也并不是像UML撤嫩,XML Schema或Java這樣的語言,它是一種自然的但經(jīng)過濃縮的領(lǐng)域語言蠢终,它是一種開發(fā)與用戶共享的語言序攘,用來描述問題和領(lǐng)域模型茴她。通用語言不是把從用戶那里聽到的內(nèi)容翻譯為開發(fā)的語言,而是為了減少誤解程奠,讓用戶更容易理解的草圖丈牢,從而可以真正的幫助糾正錯(cuò)誤,幫助開發(fā)獲取有關(guān)的領(lǐng)域新知識(shí)瞄沙。
?? 那么統(tǒng)一語言到底長什么樣子己沛?對(duì)DDD的UL沒有標(biāo)準(zhǔn)的定義,可以是圖距境,也可以是文字申尼,UML的各種圖依然是常見的表達(dá)方式,以DDD書中例子來說明下UL的一個(gè)應(yīng)用垫桂。
?? 示例:制定貨運(yùn)路線师幕,比較兩個(gè)圖和兩段溝通交流的方式

  • 場(chǎng)景1:最小化的領(lǐng)域抽象
    image.png
  • 場(chǎng)景2:用領(lǐng)域模型進(jìn)行討論
    image.png
  • 兩種溝通方式的比較
最小化的領(lǐng)域抽象 用領(lǐng)域模型進(jìn)行討論
用戶 那么,當(dāng)更改清關(guān)(customs clearance)地點(diǎn)時(shí)①诬滩,需要重新制定整個(gè)路線計(jì)劃啰霹粥。 那么,當(dāng)更改清關(guān)地點(diǎn)時(shí)疼鸟,需要重新制定整個(gè)路線計(jì)劃啰后控。
開發(fā)人員 是的。我們將從貨運(yùn)表(shipment table)中刪除所有與該貨物id相關(guān)聯(lián)的行愚臀,然后將出發(fā)地忆蚀、目的地和新的清關(guān)地點(diǎn)傳遞給Routing Service矾利,它會(huì)重新填充貨運(yùn)表姑裂。Cargo中必須設(shè)立一個(gè)布爾值,用于指示貨運(yùn)表中是否有數(shù)據(jù)男旗。 是的舶斧。當(dāng)更改Route Specification(路線說明)的任意屬性時(shí),都將刪除原有的Itinerary(航線)察皇,并要求Routing Service(路線服務(wù))基于新的Route Specification生成一個(gè)新的Itinerary茴厉。
用戶 刪除行?好什荣,就按你說的做矾缓。但是,如果先前根本沒有指定清關(guān)地點(diǎn)稻爬,也需要這么做嗎嗜闻? 如果先前根本沒有指定清關(guān)地點(diǎn),也需要這么做嗎桅锄?
開發(fā)人員 是的琉雳,無論何時(shí)更改了出發(fā)地样眠、目的地或清關(guān)地點(diǎn)(或是第一次輸入),都將檢查是否已經(jīng)有貨運(yùn)數(shù)據(jù)翠肘,如果有檐束,則刪除它們,然后由Routing Service重新生成數(shù)據(jù)束倍。 是的被丧,無論何時(shí)更改了Route Spec的任何屬性,都將重新生成Itinerary绪妹。這也包括第一次輸入某些屬性晚碾。
用戶 當(dāng)然,如果原有的清關(guān)數(shù)據(jù)碰巧是正確的喂急,我們就不需要這樣做了格嘁。 當(dāng)然,如果原有的清關(guān)數(shù)據(jù)碰巧是正確的廊移,我們就不需要這樣做了糕簿。
開發(fā)人員 哦,沒問題狡孔。但讓Routing Service每次重新加載或卸載數(shù)據(jù)會(huì)更容易些懂诗。 哦,沒問題苗膝。但讓Routing Service每次重新生成一個(gè)Itinerary會(huì)更容易些殃恒。
用戶 是的,但為新航線制定所有支持計(jì)劃的工作量很大辱揭,因此离唐,除非非改不可,我們一般不想更改航線问窃。 是的亥鬓,但為新航線制定所有支持計(jì)劃的工作量很大,因此域庇,除非非改不可嵌戈,我們一般不想更改路線。
開發(fā)人員 哦听皿,好的熟呛,當(dāng)?shù)谝淮屋斎肭尻P(guān)地點(diǎn)時(shí)褐墅,我們需要查詢表格鄙才,找到以前的清關(guān)地點(diǎn),然后與新的清關(guān)地點(diǎn)進(jìn)行比較凛虽,從而判斷是否需要重做。 哦偿短。那么需要在Route Specification添加一些功能欣孤。這樣,當(dāng)更改Route Specification中的屬性時(shí)昔逗,查看Itinerary是否仍滿足Specification降传。如果不滿足,則需要由Routing Service重新生成Itinerary勾怒。
用戶 這個(gè)處理不必考慮出發(fā)地和目的地婆排,因?yàn)楹骄€在此總要變更。 這一點(diǎn)不必考慮出發(fā)地和目的地笔链,因?yàn)镮tinerary在此總是要變更的段只。
開發(fā)人員 好的,我明白了鉴扫。 好的赞枕,但每次只做比較就簡單多了。只有當(dāng)不滿足Route Specification時(shí)坪创,才重新生成Itinerary炕婶。

?? 很明顯,這兩段對(duì)話有意使用了相似的結(jié)構(gòu)莱预,第一段對(duì)話顯得更啰嗦柠掂,對(duì)話雙方需要不斷對(duì)應(yīng)用程序的特性和表達(dá)不清的地方進(jìn)行解釋。第二段對(duì)話使用了基于領(lǐng)域模型的術(shù)語依沮,因此討論更簡潔涯贞,表達(dá)了領(lǐng)域?qū)<业母嘁鈭D。在這兩段對(duì)話中危喉,用戶都使用了“itinerary”這個(gè)詞宋渔,但在第二段中它是一個(gè)對(duì)象,這使得雙方可以更準(zhǔn)確姥饰、具體地進(jìn)行討論傻谁。他們明確討論了“route specification”,而不是每次都通過屬性和過程來描述它列粪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谈飒,隨后出現(xiàn)的幾起案子岂座,更是在濱河造成了極大的恐慌,老刑警劉巖杭措,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件费什,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡手素,警方通過查閱死者的電腦和手機(jī)鸳址,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門瘩蚪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稿黍,你說我怎么就攤上這事疹瘦。” “怎么了巡球?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵言沐,是天一觀的道長。 經(jīng)常有香客問我酣栈,道長险胰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任矿筝,我火速辦了婚禮起便,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窖维。我一直安慰自己缨睡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布陈辱。 她就那樣靜靜地躺著奖年,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沛贪。 梳的紋絲不亂的頭發(fā)上陋守,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音利赋,去河邊找鬼水评。 笑死,一個(gè)胖子當(dāng)著我的面吹牛媚送,可吹牛的內(nèi)容都是我干的中燥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼塘偎,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼疗涉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吟秩,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤咱扣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后涵防,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闹伪,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了偏瓤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杀怠。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖厅克,靈堂內(nèi)的尸體忽然破棺而出赔退,到底是詐尸還是另有隱情,我是刑警寧澤已骇,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布离钝,位于F島的核電站,受9級(jí)特大地震影響褪储,放射性物質(zhì)發(fā)生泄漏卵渴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一鲤竹、第九天 我趴在偏房一處隱蔽的房頂上張望浪读。 院中可真熱鬧,春花似錦辛藻、人聲如沸碘橘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痘拆。三九已至,卻和暖如春氮墨,著一層夾襖步出監(jiān)牢的瞬間纺蛆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工规揪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桥氏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓猛铅,卻偏偏與公主長得像字支,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奸忽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容