什么是DDD
DDD是英文Domain-Driven Design的簡稱糟把,在2004年由Eric Evans提出的一套軟件設(shè)計的概念和方法論亩钟。
DDD并不是關(guān)于技術(shù)的乓梨,而是關(guān)于討論、聆聽清酥、理解扶镀、發(fā)現(xiàn)業(yè)務(wù)價值的,而這些都是為了將知識集中起來焰轻。將領(lǐng)域?qū)<乙氲綀F隊是大有好處的臭觉。
- 領(lǐng)域?qū)<也灰姷镁椭浪械臉I(yè)務(wù),他們也得學(xué)習(xí)辱志。你向領(lǐng)域?qū)<姨岢龅膯栴}有可能暴露出他們不知道的地方蝠筑。
- 領(lǐng)域?qū)<也皇且粋€職位,他可以是精通業(yè)務(wù)的任何人揩懒。
- 領(lǐng)域模型是關(guān)于某個特定業(yè)務(wù)領(lǐng)域的軟件模型什乙。通常,領(lǐng)域模型通過對象模型來實現(xiàn)已球,這些對象同時包含了數(shù)據(jù)和行為臣镣,并且表達(dá)了準(zhǔn)確的業(yè)務(wù)含義。
開發(fā)過程中智亮,最大的鴻溝之一便存在于領(lǐng)域?qū)<液烷_發(fā)者之間忆某,通常,領(lǐng)域?qū)<覍㈥P(guān)注點放在交付業(yè)務(wù)價值上阔蛉,而開發(fā)者則將注意力放在技術(shù)實現(xiàn)上弃舒。
影響:領(lǐng)域?qū)<液烷_發(fā)者雖一同工作,他們之間的協(xié)作也只是表面的状原。過程中產(chǎn)生了一種映射:將業(yè)務(wù)人員所想的映射到開發(fā)者所理解的聋呢。這樣苗踪,軟件便不能完全反映出領(lǐng)域?qū)<业乃季S模型。這種鴻溝將增加軟件的開發(fā)成本坝冕。隨著開發(fā)者轉(zhuǎn)到其他項目或離職徒探,本應(yīng)駐留在軟件中的領(lǐng)域知識也就丟失了。
另一個問題喂窟,發(fā)生在多個領(lǐng)域?qū)<抑g存在分歧的時候。因為每個專家只熟悉某個或者某些特定領(lǐng)域央串。另外在某個領(lǐng)域找不到真正的專家也是可能的磨澡,此時,有人可能對領(lǐng)域有所了解质和,但他更像一個業(yè)務(wù)分析員稳摄。這些問題將導(dǎo)致相互矛盾的軟件模型。
更糟的是饲宿,軟件的技術(shù)實現(xiàn)可能錯誤地改變軟件的業(yè)務(wù)規(guī)則厦酬。比如:ERP軟件通常修改業(yè)務(wù)操作以滿足某個特定用戶的需求。解決方案才是主要的投入瘫想。
DDD的作用是簡化仗阅,而不是復(fù)雜化。我們應(yīng)該采用最簡單的方式對復(fù)雜領(lǐng)域進(jìn)行建模国夜,而不是使問題變得更加復(fù)雜减噪。
貧血領(lǐng)域?qū)ο笥谐霈F(xiàn)的原因:它反映了一種自然的過程式的編程風(fēng)格。很多開發(fā)者都是學(xué)著示例代碼做開發(fā)车吹,通過情況下筹裕,示例代碼只是盡可能簡單的方式來展示某個特定的概念或API特性,而并不強調(diào)要遵循多好的設(shè)計原則窄驹。
如何DDD
DDD兩大支柱:
- 通用語言朝卒。在邊界之內(nèi)的每種領(lǐng)域術(shù)語、詞組或句子乐埠,是團隊自己創(chuàng)建的公用語言浴讯,團隊中同時包含領(lǐng)域?qū)<液蛙浖_發(fā)人員。其都有確定的上下文含義驶臊,在邊界之外谆级,這些可能表示不同的意思。 通用詞不是業(yè)務(wù)語言;不必完全采用工業(yè)標(biāo)準(zhǔn)術(shù)語扯罐;不是領(lǐng)域?qū)<覍S玫摹?/li>
- 限界上下文(Bounded Context)负拟。整個應(yīng)用程序之內(nèi)的一個概念性邊界。
掌握通用語言的方法:
- 同時繪制物理模型圖和概念模型圖歹河,并標(biāo)以名字和行為掩浙。雖然這些圖并不是正式的設(shè)計圖花吟,但它們卻包含了軟件建模的某些方面。即使你的團隊在使用統(tǒng)一建模語言UML來完成正式建模厨姚,也不要得意忘形衅澈,因為這樣可能反而不利于團隊的討論,最終將阻礙通用語言的產(chǎn)生谬墙。
- 創(chuàng)建一個包含簡單定義的術(shù)語表今布。將你能想到的術(shù)語都羅列出來,包括好的和不好的拭抬,并注明好與不好的原因部默。在你給術(shù)語下定義時,你在不經(jīng)意間就會創(chuàng)造出一些可重用的詞匯造虎,因為此時你使用的是領(lǐng)域中的通用 語言傅蹂。
- 如果你不喜歡術(shù)語表,可以采用其他類型的文檔算凿,但是記得將那些“不正式”的模型圖也包含進(jìn)去份蝴。同樣,這里最終的目的也是發(fā)現(xiàn)通用語言中的術(shù)語和詞組氓轰。
- 由于團隊中有些人工作在術(shù)語表上婚夫,還有些人工作在文檔上,此時你需要找到團隊的其他人員來檢查你的成果戒努。分歧肯定是有的请敦,你應(yīng)該對此有所準(zhǔn)備。
- 這樣建立起來的模型不能直接用于指導(dǎo)開發(fā)储玫,而只是建立通用語言的起步而已侍筛。此后改進(jìn)之后的通用語言將反映到系統(tǒng)的源代碼中。通用語言會過時撒穷,只有團隊的交流和代碼才能持續(xù)到最后匣椰,也只有這兩者才能實時地反映通用語言。
- 由于團隊交流和代碼才是對通用語言的持續(xù)表達(dá)端礼,你應(yīng)該試著拋棄那些模型圖禽笑、術(shù)語表和文檔。這樣做的原因是蛤奥,我們很難將項目文檔和軟件系統(tǒng)保持同步佳镜。對通用語言達(dá)成一致后,才開始著手開發(fā)凡桥。對領(lǐng)域模型的修改也將導(dǎo)致對應(yīng)用層的修改蟀伸。每個應(yīng)用層的方法都對應(yīng)著一個單一的用例流。
對通用語言的理解:
- 通用意思是“普遍的”,或者“到處都存在的“啊掏。通用 語言在團隊范圍內(nèi)使用蠢络,并且只表達(dá)一個單一的領(lǐng)域模型。
- “通用語言”并不表示全企業(yè)迟蜜、全公司或者全球性的萬能領(lǐng)域語言刹孔。
- 限界上下文和通用語言間存在一對一的關(guān)系。
- 限界上下文是一個相應(yīng)較小的概念娜睛,通常比我們起初的想象的要小髓霞。限界上下文剛好能夠容納下一個獨立的限界上下文中所使用的通用語言。
- 只有當(dāng)團隊工作在一個獨立的限界上下文中時微姊,通用語言才是”通用“的酸茴。
- 雖然我們只工作在一個限界上下文中,但是通常我們還需要和其他限界上下文打交道兢交,這時可以通用上下文映射圖對這些限界上下文進(jìn)行集成。每個限界上下文都有自己的通用語言笼痹,而有時語言間的術(shù)語可能有重疊的地方配喳。
- 如果你試圖將某個通用語言運用到整個企業(yè)范圍之內(nèi),或者更大的凳干、跨企業(yè)的范圍內(nèi)晴裹,你將失敗。
通用語言((ubiquitous language)實例
個人(實體):包含并管理用戶的個人信息.包括名字和聯(lián)系方式等救赐。
激活租戶:通過該操作激活一個租戶涧团,激活后再對租戶的當(dāng)前狀態(tài)進(jìn)行確認(rèn)。
禁用租戶:通過該操作禁用一個租戶经磅,在禁用一個租戶時泌绣,用戶可能還沒有被認(rèn)證。
認(rèn)證服務(wù):協(xié)調(diào)對用戶的認(rèn)證過程预厌,首先需要保證他們所屬的租戶處于激活狀態(tài)阿迈。