Repository 倉儲你可以結(jié)合測試驅(qū)動開發(fā)就知道沒什么了,DDDTDD,其實領(lǐng)域模型最好的業(yè)務(wù)體現(xiàn)是在哪?不是在領(lǐng)域模型,而是領(lǐng)域模型的單元測試,它是很好的描述這個業(yè)務(wù)用例,如果你的領(lǐng)域模型的單元測試出了問題,那就是領(lǐng)域模型出了問題,其實兄臺可以試著寫下你這個業(yè)務(wù)場景下的領(lǐng)域模型的單元測試,也就是一個業(yè)務(wù)用例的單元測試,看看會發(fā)生什么?還有就是應(yīng)用層的偽代碼。反之,電視行業(yè)的關(guān)鍵轉(zhuǎn)折,倒是上層,如控制器這里不應(yīng)該用倉儲。”其實原本大家的焦點不應(yīng)該放在倉儲上面的,而應(yīng)該放在領(lǐng)域驅(qū)動設(shè)計的核心領(lǐng)域模型上,為此我還曾寫了幾篇關(guān)于領(lǐng)域模型設(shè)計的博文,但是一個完整的應(yīng)用程序不只是包含領(lǐng)域模型,還有其他的東西需要進行探討,雖然它不像領(lǐng)域模型那么重要,但同樣必不可少以下內(nèi)容只是個人對倉儲概念及其問題進行探討,并非是結(jié)論總結(jié),僅供各位仁兄參考《實現(xiàn)領(lǐng)域驅(qū)動設(shè)計》這本書,我在之前覺得沒必要閱讀,因為當時認為學習領(lǐng)域驅(qū)動設(shè)計,只要精讀下 Eric Evans 的經(jīng)典著作《領(lǐng)域驅(qū)動設(shè)計軟件核心復(fù)雜性應(yīng)對之道》就可以了,但是DDD是需要進行實踐的,Eric Evans 只是提出領(lǐng)域驅(qū)動設(shè)計這個概念,有關(guān)于其實現(xiàn),書中并沒有花很大的精力去講解,而《實現(xiàn)領(lǐng)域驅(qū)動設(shè)計》這本書正是彌補了這一點這兩本書的閱讀順序,當然是先閱讀《領(lǐng)域驅(qū)動設(shè)計》,然后再閱讀《實現(xiàn)領(lǐng)域驅(qū)動設(shè)計》,如果你是第一次讀第一本書,它會顛覆你對軟件設(shè)計的一些看法,然后讓你不能自拔的“愛上它”,不知道你有沒有,反正我是這樣,然后你在做一些應(yīng)用程序設(shè)計的時候,會嘗試使用領(lǐng)域驅(qū)動設(shè)計,雖然有些步履蹣跚,城市宣傳片—“北京旅游宣企業(yè)宣傳片制作-北京旅游宣傳片2013,但是走出第一步是很重要的。關(guān)于閱讀第二本書,我的建議是,在閱讀之前,先根據(jù)第一本書中的指導(dǎo),自己嘗試去實踐領(lǐng)域驅(qū)動設(shè)計,最好是做一些實際業(yè)務(wù)場景的應(yīng)用,在這個過程中,完全按照自己對領(lǐng)域驅(qū)動設(shè)計的想法去實現(xiàn),雖然可能會掉進一些深坑,但是我覺得只有這樣你才會理解的更加深刻也可以像 dudu 這樣進行直白的理解:Repository 是一個獨立的層,介于領(lǐng)域?qū)优c數(shù)據(jù)映射層(數(shù)據(jù)訪問層)之間。它的存在讓領(lǐng)域?qū)痈杏X不到數(shù)據(jù)訪問層的存在,它提供一個類似集合的接口提供給領(lǐng)域?qū)舆M行領(lǐng)域?qū)ο蟮脑L問。Repository 是倉庫管理員,領(lǐng)域?qū)有枰裁礀|西只需告訴倉庫管理員,由倉庫管理員把東西拿給它,并不需要知道東西實際放在哪。除了這兩個關(guān)鍵詞,還有一個動詞就是協(xié)調(diào),倉儲協(xié)調(diào)的是什么?怎么協(xié)調(diào)的?這個概念需要明確下,橋的一頭領(lǐng)域模型(主要是實體對象),這個就不多說了,橋的另一頭ORM(對象關(guān)系映射),因為我們大部分情況下使用的是關(guān)系型數(shù)據(jù)庫,如何對數(shù)據(jù)進行管理?當然 DAO 是一種(這邊先不多說),一部滿是套路的漫威宇宙電影,還有就是使用 ORM,它可以讓你很方便的進行數(shù)據(jù)和對象映射轉(zhuǎn)換,如果你的項目是基于事務(wù)腳本模式設(shè)計的,那就沒必要使用 ORM 工具了,因為使用簡單的 SQL 更合適,說了這么多,好像都沒說到重點,其實倉儲協(xié)調(diào)的是 ORM 中的“O”,也就是對象的概念,它是在數(shù)據(jù)映射層之上的,是一種概念,而不是一種實現(xiàn),這個概念很重要有時候,倉儲和數(shù)據(jù)訪問對象會當作同義詞來看待,因為他們都提供了對持久化機制的抽象,在 DAO 中比較好理解,倉儲中的持久化機制主要體現(xiàn)在 ORM 中,但是這并不屬于倉儲,影視視頻制作更不屬于 DAO,所以有時候我們認為所有的持久化抽象稱為 DAO,并不是很準確,我們需要確定的是這種模式是否得到了真正的實現(xiàn)倉儲和 DAO 是不同的,一個 DAO 主要從數(shù)據(jù)庫表的角度來看待問題,并且提供 CRUD 操作,這種模式適用于事務(wù)腳本程序中,這是因為,這些與 DAO 相關(guān)的模式通常只是對數(shù)據(jù)庫表的一層封裝。而另一方面,倉儲和數(shù)據(jù)影射器(ORM)則更加偏向于對象,因此通常被用于領(lǐng)域模型中有關(guān)倉儲和數(shù)據(jù)訪問對象的探討,最后的結(jié)論是,通常來說,你可以將倉儲當作 DAO 來看待,但是請注意一點,在設(shè)計倉儲時,我們應(yīng)該采用面向集合的方式,影視視頻制作而不是面向數(shù)據(jù)訪問的方式。這有助于你將自己的領(lǐng)域當作模型來看待,而不是 CRUD 操作有人可能會依賴于ORM所提供的生命周期事件來完成對象的級聯(lián)刪除。我刻意地沒有使用這種方式,因為我強烈反對由聚合來管理持久化,同時我強烈地提倡只使用資源庫來處理持久化。當然,有關(guān)這兩者的爭論非常激烈,并且還在繼續(xù)。因此,在選擇時,你需要多方權(quán)衡。但是請記住,DDD專家是不會首先考慮使用聚合來管理持久化的根據(jù)我的猜測,大概是這樣的意思,主要是倉儲的持久化管理,一種是使用 ORM 攻擊所提供的持久化機制,公司宣傳片拍攝這種方式就使得倉儲依賴于這些技術(shù)的實現(xiàn),但是可以為我們在實現(xiàn)倉儲的時候省去很多事,比如我們使用 EntityFramework,你會發(fā)現(xiàn)我們在實現(xiàn)倉儲的時候,變得異常簡單9,count() or size()? 我們有時候計算聚合實例的總數(shù),一般會將實現(xiàn)方法命名為 count(),但是因為倉儲應(yīng)該盡可能的模擬一個集合,因此建議接口定義如下:命名規(guī)則是我們在軟件開發(fā)過程中,最容易忽略的一點,可能在一般的開發(fā)過程中不注意會沒事,但是在領(lǐng)域驅(qū)動設(shè)計中,就像之前所表述的那樣,代碼代表著一種語言,不光是自己能看懂,還要讓需求人員可以看懂,至少可以從名字上知道其代表的意思,這一點很重要10,聚合根下的子聚合正確方式有時,如果我們要獲取聚合根下的某些子聚合,夜景攝像的幾點提示,我們不用先從資源庫中獲取到聚合根,然后再從聚合根中獲取這些子聚合,而是可以直接從資源庫中返回。在有些情況下,這種做法是有好處的。比如,某個聚合根擁有一個很大的實體類型集合,而你需要根據(jù)某種查詢條件返回該集合中的一部分實體。當然,只有在聚合根中提供了對該實體集合的導(dǎo)航時,我們才能這么做,否則,我們便違背了聚合的設(shè)計原則。我建議不要因為客戶端的方便而提供這種訪問方式。更多的時候,采用這種方式是由于性能上的考慮,比如從聚合根中訪問子聚合將帶來性能瓶頸的時候。此時的查找方法和其他查找方法具有相同的基本特征,只是它直接返回聚合根下的子聚合,而不是聚合根本身。無論如何,請慎重使用這種方式。除了這個問題之外,還有一個就是倉儲執(zhí)行完查詢后,有時候會返回多個聚合的查詢結(jié)果對象,這個我們一般會將查詢結(jié)果放在一個值對象中11,CQRS 模式引入對于 CQRS 模式,我沒有深入研究過,更沒有實踐應(yīng)用過,我的想法是先去把經(jīng)典DDD理解透,然后再去嘗試其他東西,畢竟路要一步一步走,CQRS 模式是對 DDD 的一種很好補充,也就是說它的產(chǎn)生是有一定的理由的,對于領(lǐng)域驅(qū)動設(shè)計初學者,我個人不建議,一開始就使用 CQRS 模式當我們使用用例優(yōu)化查詢時,有時候我們必須創(chuàng)建多個查詢方法,什么意思?就是跨聚合查詢,這可能意味著你的聚合邊界劃分的有問題,如果你確定你的聚合邊界劃分沒有問題,那你應(yīng)該考慮使用 CQRS 模式了,它的應(yīng)用場景就是這樣,凡事都有產(chǎn)生的原因,如果你的應(yīng)用程序沒有很復(fù)雜的查詢操作,我個人覺得,完全沒必要使用 CQRS 模式,有時候不要為了實現(xiàn)而實現(xiàn)。