新聞中心
***部分:.NET領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)—初嘗

【1.3】原則
| 原則對(duì)于任何一項(xiàng)技術(shù)實(shí)現(xiàn)來(lái)說(shuō)都是至關(guān)重要的,在設(shè)計(jì)某一個(gè)系統(tǒng)功能的時(shí)候我們講究的是設(shè)計(jì)原則: |
【單一職責(zé)原則Single Responsibility Principle、里氏替換原則Liskov Substitution Principle、依賴倒置原則Dependence Inversion Principle、接口隔離原則Interface Segregation Principle、迪米特法則Law Of Demeter、開(kāi)閉原則Open Close Principle】。
在架構(gòu)設(shè)計(jì)的時(shí)候我們也講究架構(gòu)原則:
【分層原則、避免循環(huán)依賴】。
不僅僅在技術(shù)領(lǐng)域在做人做事都要講究原則,違背原則那么等待你的將是無(wú)情的懲罰。
對(duì)于DDD的設(shè)計(jì)我們也有相應(yīng)的原則需要遵守,當(dāng)然如果不遵守在前期看不出什么區(qū)別,但是到開(kāi)發(fā)階段問(wèn)題就會(huì)暴露出來(lái)。
我們來(lái)看兩個(gè)基本的設(shè)計(jì)原則問(wèn)題。
【精簡(jiǎn)聚合】
精簡(jiǎn)聚合的設(shè)計(jì)原則無(wú)疑是最重要的。一些軟件工程方法論書(shū)籍經(jīng)常指導(dǎo)我們進(jìn)行UML業(yè)務(wù)建模,"在這個(gè)階段不需要考慮任何技術(shù)實(shí)現(xiàn)問(wèn)題”,我按照這樣的指導(dǎo)原則進(jìn)行了UML的設(shè)計(jì)然后順利的創(chuàng)建出ER關(guān)系圖,結(jié)果發(fā)現(xiàn)那樣的數(shù)據(jù)庫(kù)結(jié)構(gòu)根本不能作為最終的項(xiàng)目開(kāi)發(fā)數(shù)據(jù)庫(kù)。哪里出問(wèn)題了?我反復(fù)查詢指導(dǎo)書(shū)籍后來(lái)在專業(yè)的DDD書(shū)籍上看到了一句大概這樣的話:
【“不以技術(shù)實(shí)現(xiàn)為前提的設(shè)計(jì)都是紙上談兵”】。
我想這句話很真實(shí)的描述了方法論與企業(yè)應(yīng)用之間的鴻溝,很多技術(shù)思想或者理論確實(shí)很好,但是要想用起來(lái)需要解決很多問(wèn)題。DDD也避免不了這個(gè)問(wèn)題,怎么避免在設(shè)計(jì)UML模型的時(shí)候不會(huì)導(dǎo)致設(shè)計(jì)過(guò)度的問(wèn)題,這里我們只需要遵守【精簡(jiǎn)聚合】原則就不會(huì)導(dǎo)致設(shè)計(jì)過(guò)度問(wèn)題。
在前面的例子當(dāng)中我們?cè)O(shè)計(jì)一個(gè)完整的UML領(lǐng)域模型,但是我們并沒(méi)有對(duì)它進(jìn)行【精簡(jiǎn)聚合】重構(gòu),所以它存在的問(wèn)題就是無(wú)法進(jìn)行項(xiàng)目開(kāi)發(fā)。
1.1圖
我們構(gòu)建出來(lái)的領(lǐng)域模型初步版本應(yīng)該是上圖這樣的,實(shí)體與實(shí)體之間是有強(qiáng)聯(lián)系的,聚合之間的關(guān)聯(lián)太大,導(dǎo)致?tīng)恳话l(fā)而動(dòng)全身。如果按照這種關(guān)系創(chuàng)建數(shù)據(jù)庫(kù)那么數(shù)據(jù)庫(kù)之間的主\外鍵肯定很多,對(duì)數(shù)據(jù)庫(kù)的設(shè)計(jì)造成了影響。這樣的關(guān)系如果在程序中使用也會(huì)存在很多問(wèn)題,我們無(wú)法進(jìn)行少數(shù)聚合的使用,當(dāng)我們使用某一個(gè)聚合的時(shí)候它會(huì)接二連三的把相關(guān)聯(lián)的聚合都給拖出來(lái),不僅在查詢的時(shí)候妨礙而且在Factory創(chuàng)建聚合的時(shí)候也會(huì)存在無(wú)法構(gòu)造的問(wèn)題,不管在對(duì)聚合Repository進(jìn)行任何操作的時(shí)候都會(huì)影響程序邏輯,所以我們需要對(duì)一個(gè)復(fù)雜的龐大的關(guān)系進(jìn)行拆分。
將紅線的部分全部斷開(kāi),聚合之間通過(guò)Id進(jìn)行關(guān)聯(lián),這樣就會(huì)變的很清晰。因?yàn)楹苌俪绦蛑袝?huì)在某一個(gè)業(yè)務(wù)邏輯點(diǎn)上需要所有的業(yè)務(wù)模型參與,這樣既方便了程序的開(kāi)發(fā)也方便了數(shù)據(jù)庫(kù)的設(shè)計(jì),更方便了ORM的使用。ORM的延遲加載其實(shí)就是為了聚合之間的依賴,可以在需要的時(shí)候在去查詢需要的模型。但是這樣雖然程序可以說(shuō)的過(guò)去,那么數(shù)據(jù)庫(kù)的設(shè)計(jì)就說(shuō)不過(guò)去了。對(duì)于不同的ORM框架的映射原理不同,在構(gòu)造模型的時(shí)候是需要稍微的調(diào)整的,比如在EntityFramework中,它能支持的映射方案你保證你的模型能順利的映射過(guò)去,這里就不扯了后面有一個(gè)詳細(xì)的項(xiàng)目做全面實(shí)踐,到時(shí)候在具體問(wèn)題具體分析。
***我們看一下分解后的類圖:
1.2圖
這樣一來(lái)一塊一塊很清晰,都能直接使用相關(guān)的核心領(lǐng)域模型,也不需要擔(dān)心ORM框架的延遲加載的問(wèn)題。
【分離用例與功能接口(設(shè)計(jì)模式的使用之地)】
分離用例與功能接口其實(shí)也是初次接觸DDD的朋友都會(huì)犯的職業(yè)病,因?yàn)槲覀兌际煜っ嫦驅(qū)ο笤O(shè)計(jì)。在進(jìn)行UML建模的時(shí)候我們都非常喜歡抽象,會(huì)很清楚的把具有泛化關(guān)系的用繼承來(lái)表示,比如【用戶類型】,不同的用戶具有不同的行為權(quán)限,在初步設(shè)計(jì)的時(shí)候我們一般都會(huì)建立關(guān)于用戶的一個(gè)繼承關(guān)系來(lái)表達(dá)泛化的業(yè)務(wù)模型。但是在編碼階段會(huì)發(fā)現(xiàn)很明顯的問(wèn)題就是我們把關(guān)于Repository的行為包含到了發(fā)起用例的用戶聚合當(dāng)中去了,這樣說(shuō)可能有點(diǎn)抽象。我們還是用例子來(lái)分析;
1.3圖
上圖中我將【Admin】和【配送】用例分開(kāi)了,想表達(dá)是不能將關(guān)于配送的行為放在【Admin】中。在我們對(duì)有關(guān)權(quán)限進(jìn)行建模的時(shí)候經(jīng)常會(huì)潛意識(shí)的將各自的行為放在了各自的角色當(dāng)中,如果后期存在多角色共享行為的就將寫(xiě)在抽象的類中使用虛方法向下傳遞。問(wèn)題就出在關(guān)于角色行為里,我們知道如果有行為那么就有可能在該行為里面執(zhí)行有關(guān)其他聚合的IRepository操作,這樣一來(lái)將會(huì)把領(lǐng)域模型搞的很亂,無(wú)法垂直分析。
1.4圖
DDD講究領(lǐng)域驅(qū)動(dòng),在我們看來(lái)【Dispatching】、【CheckOrders】都是繼承管理員角色,管理員屬于后臺(tái)管理人員,意味著企業(yè)的員工。對(duì)消費(fèi)者來(lái)說(shuō)他們就是管理人員。同樣消費(fèi)者也會(huì)存在相同的情況,消費(fèi)者可能存在很多種類型,有VIP系列的(VIP1\VIP2\VIP3…),有鉆石會(huì)員之類的。如果這樣設(shè)計(jì)的話并不能說(shuō)是錯(cuò)的,這也完全符合DDD的思想要求,但是實(shí)際情況下卻是不理想的。
這里就用到了我們長(zhǎng)期使用的設(shè)計(jì)模式了,我們可以通過(guò)設(shè)計(jì)模式中的很多中模式來(lái)將用戶與行為分離開(kāi)來(lái),再將使用的規(guī)則條件抽象出來(lái)就完全獨(dú)立了用戶,用戶在使用的時(shí)候不會(huì)存在直接的行為歸屬,但是事實(shí)上他們確實(shí)是有行為。
1.5圖
用專業(yè)的DDD術(shù)語(yǔ)講“規(guī)約模式”,將業(yè)務(wù)規(guī)則抽取出來(lái)對(duì)象化,甚至到***都可以進(jìn)行規(guī)則的配置化。最讓我們興奮的是,我們苦心學(xué)習(xí)的設(shè)計(jì)模式終于可以在系統(tǒng)設(shè)計(jì)中大面積的使用了,難道不是一件很驚喜的事情嗎!
#p#
【1.4】工具、框架
任何一種架構(gòu)都是需要框架、工具的支撐才能變的***。
當(dāng)我們?cè)谀撤N架構(gòu)下進(jìn)行開(kāi)發(fā)的時(shí)候,我們必須需要很多工具、框架的支撐才能讓開(kāi)發(fā)工作變的很便捷,這也和【敏捷開(kāi)發(fā)】的思想一樣。在傳統(tǒng)的三層架構(gòu)下開(kāi)發(fā)我們都需要 "對(duì)象映射"、"AOP\IOC” 等等類似的輔助框架,目的是為了架構(gòu)前行的可能性。在DDD中我們也需要很多目前還沒(méi)有出現(xiàn)的很多工具、框架,在.NET平臺(tái)中目前來(lái)看只有EntityFramework框架算是為了DDD做了很多工作,如果我們的領(lǐng)域模型無(wú)法與數(shù)據(jù)庫(kù)進(jìn)行映射,那么領(lǐng)域模型開(kāi)發(fā)所要付出的代價(jià)將是很大。
在設(shè)計(jì)階段我們?nèi)狈σ粋€(gè)面向特定領(lǐng)域的建模工具,這種工具與UML不同,UML太技術(shù)化通用化。DDD中經(jīng)常會(huì)提起【領(lǐng)域?qū)<摇恳唤?,他?**有權(quán)威性的領(lǐng)域領(lǐng)頭人,我們所創(chuàng)建出來(lái)的UML他們未必能看得懂,通過(guò)技術(shù)人員技術(shù)化之后形成UML其實(shí)已經(jīng)變味,【領(lǐng)域?qū)<摇渴嵌嵌臒o(wú)法做到肯定的保證。如果能把領(lǐng)域模型語(yǔ)言化,那么這個(gè)將是一大成就。【領(lǐng)域?qū)<摇繉?duì)領(lǐng)域中的任何事物、人物、環(huán)節(jié)都很熟悉,但是他無(wú)法表達(dá)清楚自己的想法,如果能有一個(gè)工具輔助他的設(shè)計(jì),該工具能將設(shè)計(jì)后的模型進(jìn)行平滑等價(jià)的技術(shù)化變成代碼模型或者數(shù)據(jù)庫(kù)模型,這一條鴻溝如果能跨越那么對(duì)行業(yè)來(lái)說(shuō)具有很大影響力。
1.8圖
如果我們能等價(jià)的將上圖中的真實(shí)模型進(jìn)行技術(shù)化,那么真的每個(gè)人都會(huì)喜歡需求分析、分析設(shè)計(jì)。
既然是模型驅(qū)動(dòng)設(shè)計(jì),我們?cè)诮o用戶分析類似這樣一套系統(tǒng)的時(shí)候,前提是我們已經(jīng)對(duì)里面的所有細(xì)節(jié)進(jìn)行了抽象封裝,每一個(gè)過(guò)程都是可以拆分的,***能合并在一起形成一個(gè)整體的業(yè)務(wù)模型。當(dāng)然這里只是一種技術(shù)展望,也是我們奮斗和理想的目標(biāo)。
推薦一本***Martin Fowler的書(shū):《領(lǐng)域特定語(yǔ)言》
【1.5】過(guò)程
DDD不是一種純技術(shù)實(shí)現(xiàn),而是一整套開(kāi)發(fā)思想,它貫穿軟件開(kāi)發(fā)的所有生命周期。從我們開(kāi)發(fā)接觸領(lǐng)域,對(duì)領(lǐng)域知識(shí)進(jìn)行深入的消化,這些都是DDD所強(qiáng)調(diào)的。那么在我們?nèi)粘i_(kāi)發(fā)過(guò)程中,我們?cè)撊绾翁幚磉@些過(guò)程,需求不會(huì)再像以前那樣是一份雜亂無(wú)章的草稿,而是一個(gè)內(nèi)容豐富的領(lǐng)域模型草圖。這樣的要求對(duì)團(tuán)隊(duì)對(duì)部門甚至對(duì)公司來(lái)說(shuō)都是一個(gè)提升,要想做到完全的DDD過(guò)程其實(shí)很難。
公司領(lǐng)導(dǎo)如何看待這樣的開(kāi)發(fā)方式,我們多數(shù)人都是在一些非專業(yè)研發(fā)類的公司工作,領(lǐng)導(dǎo)希望能盡早的看到東西,這很矛盾,需要好的東西但是不按照好的東西做法來(lái)做。如果有幸能有一個(gè)面向DDD、敏捷、XP的研發(fā)團(tuán)隊(duì)工作,那么可以視項(xiàng)目為一件終身的藝術(shù)品。[王清培版權(quán)所有,轉(zhuǎn)載請(qǐng)給出署名]
這兩篇文章主要是一些本人對(duì)DDD的感悟,分享給大家。
后面一篇文章將會(huì)詳細(xì)的使用一個(gè)DDD架構(gòu)的小系統(tǒng)作為案例給大家分享,里面將包括從需求的分析建模、設(shè)計(jì)模式的使用、數(shù)據(jù)庫(kù)映射、EntityFramework的使用等等,可以作為真實(shí)項(xiàng)目開(kāi)發(fā)的依據(jù)。
原文鏈接:http://www.cnblogs.com/wangiqngpei557/archive/2013/04/10/3012590.html
新聞名稱:.NET領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)—初嘗(二)
網(wǎng)站鏈接:http://m.fisionsoft.com.cn/article/cdeghji.html


咨詢
建站咨詢
