《領(lǐng)域驅(qū)動設(shè)計(jì)》學(xué)習(xí)筆記:第二部分-模型驅(qū)動設(shè)計(jì)的構(gòu)造塊

【?第二部分?】模型驅(qū)動設(shè)計(jì)的構(gòu)造塊

第4章:分離領(lǐng)域

模式:LAYERED ARCHTECTURE

分層模式

想要創(chuàng)建出能夠處理復(fù)雜任務(wù)的程序碑定,需要做到關(guān)注點(diǎn)分離——使設(shè)計(jì)中的每個(gè)部分得到單獨(dú)的關(guān)注。在分離的同時(shí),也需要維持系統(tǒng)內(nèi)部復(fù)雜的交互關(guān)系析砸。

分層的價(jià)值在于每一層都只代表程序中的某一特定方面的。這種限制使每個(gè)方面的設(shè)計(jì)都更具內(nèi)聚性,更容易理解。

而領(lǐng)域?qū)邮悄P偷木杌恰nI(lǐng)域模型是一些列概念的集合∥谅悖“領(lǐng)域?qū)印眲t是領(lǐng)域模型以及所有與其直接相關(guān)的設(shè)計(jì)元素的表現(xiàn)客叉,他由業(yè)務(wù)邏輯的設(shè)計(jì)和實(shí)現(xiàn)組成。在MODEL-DRIVEN-DESIGN中话告,領(lǐng)域?qū)拥能浖?gòu)造反映出了模型概念兼搏。

【學(xué)習(xí)心得】:分離意味著原始的復(fù)雜,這是發(fā)展的一個(gè)趨勢沙郭,技術(shù)的進(jìn)步往往在于精細(xì)化的分工佛呻,而這種分層的另一個(gè)好處是,分離核心病线,聚焦問題吓著。


第5章:軟件中所表示的模型

模式:ENTITY(又稱為REFERENCE OBJECT)

一些對象主要不是由它們的屬性定義的。它們實(shí)際上表示了一條“標(biāo)識線”(A Thread of Identity)氧苍,這條線跨越時(shí)間夜矗,而且常常經(jīng)歷多種不同的表示泛范。有時(shí)让虐,這樣的對象必須與另一個(gè)具有不同屬性的對象相匹配。而有時(shí)一個(gè)對象必須與具有相同屬性的另一個(gè)對象區(qū)分開罢荡。錯(cuò)誤的標(biāo)識可能會破壞數(shù)據(jù)赡突。

當(dāng)一個(gè)對象由其標(biāo)識(而不是屬性)區(qū)分時(shí),那么在模型中應(yīng)該主要通過標(biāo)識來確定該對象的定義区赵。是類定義變得簡單惭缰,并集中關(guān)注生命周期的連續(xù)性和標(biāo)識。定義一種區(qū)分每個(gè)對象的方式笼才,這種方式應(yīng)該與其形式和歷史無關(guān)漱受。要格外注意那些需要通過屬性來匹配對象的需求。在定義標(biāo)識操作時(shí)骡送,要確保這種操作為每個(gè)對象生成唯一的結(jié)果昂羡,這可以通過附加一個(gè)保證唯一性的符號來實(shí)現(xiàn)絮记。這種定義標(biāo)識的方法可能來自外部,也可能是由系統(tǒng)創(chuàng)建的任意標(biāo)示符虐先,但它在模型中必須是唯一的標(biāo)識怨愤。模型必須定義“符合什么條件才算是相同的事物”。

模式:VALUE OBJECT

很多對象沒有概念上的標(biāo)識蛹批,它們描述了一個(gè)事務(wù)的某種特征撰洗。而這類用于描述領(lǐng)域的某個(gè)方面而本身沒有概念標(biāo)識的對象稱為VALUE OBJECT(值對象)。

當(dāng)我們只關(guān)心一個(gè)模型元素的屬性時(shí)腐芍,應(yīng)把它歸類為VALUE OBJECT差导。我們應(yīng)該使這個(gè)模型元素能夠表示出其屬性的意義,并為它提供相關(guān)功能猪勇。VALUE OBJECT應(yīng)該是不可變的柿汛。不要為它分配任何標(biāo)識,而且不要把它設(shè)計(jì)成像ENTITY那么復(fù)雜埠对。

模式:SERVICE

有時(shí)络断,對象不是一個(gè)事物。在某些情況下项玛,最清楚貌笨、最實(shí)用的設(shè)計(jì)會包含一些特殊的操作,這些操作從概念上講不屬于任何對象襟沮。與其把它們強(qiáng)制地歸于哪一類锥惋,不如順其自然地在模型中引入一種新的元素,這就是SERVICE(服務(wù))开伏。

所謂SERVICE膀跌,它強(qiáng)調(diào)的是與其他對象的關(guān)系。與ENTITY和VALUE OBJECT不同固灵,它只是定義了能夠?yàn)榭蛻糇鍪裁赐鄙恕ERVICE往往是一個(gè)一活動來命名,而不是以一個(gè)ENTITY來命名巫玻,也就是說丛忆,它是動詞而不是名詞。

好的SERVICE有以下3個(gè)特征:

(1)與領(lǐng)域概念相關(guān)的操作不是ENTITY或VALUE OBJECT的一個(gè)自然組成部分仍秤。

(2)接口是根據(jù)領(lǐng)域模型的其他元素定義的熄诡。

(3)操作是無狀態(tài)的。

當(dāng)領(lǐng)域中的某個(gè)重要的過程或轉(zhuǎn)換操作不是ENTITY或VALUE OBJECT的自然職責(zé)時(shí)诗力,應(yīng)該在模型中添加一個(gè)作為獨(dú)立接口的操作凰浮,并將其聲明為SERVICE。定義接口時(shí)要使用模型語言,并確保操作名稱是UBIQUITOUS LANGUAGE中的術(shù)語袜茧。此外屿良,應(yīng)該使SERVICE成為無狀態(tài)的。

SERVICE與孤立的領(lǐng)域?qū)樱哼@種模式只重視那些在領(lǐng)域中具有重要意義的SERVICE惫周,但SERVICE并不只是在領(lǐng)域中使用尘惧。我們需要注意區(qū)分屬于領(lǐng)域?qū)拥腟ERVICE和那些屬于其他層的SERVICE,并劃分責(zé)任递递,以便將它們明確地區(qū)分開喷橙。

將SERVICE劃分到各層中(資金轉(zhuǎn)賬 示例)??

模式:MODULE(也稱為PACKAGE)

MODULE是一個(gè)傳統(tǒng)的、較成熟的設(shè)計(jì)元素登舞。雖然使用模塊有一些技術(shù)上的原因贰逾,但主要原因卻是“認(rèn)知超載”。MODULE為人們提供了兩種觀察模型的方式菠秒,一是可以在MODULE中查看細(xì)節(jié)疙剑,而不會被整個(gè)模型淹沒,二是觀察MODULE之間的關(guān)系践叠,而不考慮其內(nèi)部細(xì)節(jié)言缤。

每個(gè)人都會使用MODULE,但卻很少有人它們當(dāng)作模型中的一個(gè)成熟的組成部分禁灼。代碼按照各種各樣的類別進(jìn)行分解管挟,有時(shí)是按照技術(shù)架構(gòu)來分割的,有時(shí)是按照開發(fā)人員的任務(wù)分工來分割的弄捕。甚至那些從事大量重構(gòu)工作的開發(fā)人員也傾向于使用項(xiàng)目早期形成的一些MODULE僻孝。

眾所周知,MODULE之間應(yīng)該是低耦合的守谓,而在MODULE的內(nèi)部則是高內(nèi)聚的穿铆。耦合和內(nèi)聚的解釋使得MODULE聽上去像是一種技術(shù)指標(biāo),仿佛根據(jù)關(guān)聯(lián)和交互的分布情況來機(jī)械地判斷它們斋荞。然而荞雏,MODULE并不僅僅是代碼的劃分,而且也是概念的劃分譬猫。一個(gè)人一次考慮的事情是有限的(因此才要低耦合)讯檐。不連貫的思想和“一鍋粥”似的思想同樣難于理解(因此才要高內(nèi)聚)。

因此:選擇能夠描述系統(tǒng)的MODULE染服,并使之包含一個(gè)內(nèi)聚的概念集合。這通常會實(shí)現(xiàn)MODULE之間的低耦合叨恨,但如果效果不理想柳刮,則應(yīng)尋找一種更改模型的方式來消除概念之間的耦合,或者找到一個(gè)可以作為MODULE基礎(chǔ)的概念(這個(gè)概念先前可能被忽視了),基于這個(gè)概念組織的MODULE可以以一種有意義的方式將元素集中到一起秉颗。找到一種低耦合的概念組織方式痢毒,從而可以相互獨(dú)立地理解和分析這些概念。對模型進(jìn)行精化蚕甥,直到可以根據(jù)高層領(lǐng)域概念對模型進(jìn)行劃分哪替,同時(shí)相應(yīng)的代碼也不會產(chǎn)生耦合。MODULE的名稱應(yīng)該是UBIQUITOUS LANGUAGE中的術(shù)語菇怀。MODULE及其名稱應(yīng)反映出領(lǐng)域的深層知識凭舶。

【學(xué)習(xí)心得】:每一個(gè)概念或方法,都有其含義來源和出處爱沟。學(xué)會尋找信息的源頭帅霜,學(xué)會給自己的認(rèn)知指明來源和出處,具備嚴(yán)謹(jǐn)?shù)倪壿嬎季S呼伸,科學(xué)地學(xué)習(xí)和認(rèn)知身冀,是一切成功的基礎(chǔ)。杜絕垃圾二手信息資料括享,杜絕自我局限性拍腦袋的認(rèn)知決策過程搂根。

第6章:領(lǐng)域?qū)ο蟮氖裁粗芷?/h2>
領(lǐng)域?qū)ο蟮纳芷?/div>

模式:AGGREGATE

在具有復(fù)雜關(guān)聯(lián)的模型中,要想保證對象更改的一致性是很困難的铃辖。不僅互不關(guān)聯(lián)的對象需要遵守一些固定規(guī)則兄墅,而且緊密關(guān)聯(lián)的各組對象也要遵守一些固定規(guī)則。然而澳叉,過于謹(jǐn)慎的鎖定機(jī)制又會導(dǎo)致多個(gè)用戶之間毫無意義地互相干擾隙咸,從而使系統(tǒng)不可用。

固定規(guī)則(invariant)是指在數(shù)據(jù)變化時(shí)必須保持一致性規(guī)則成洗,其涉及AGGREGATE成員之間的內(nèi)部關(guān)系五督。而任何跨越AGGREGATE的規(guī)則將不要求每時(shí)每刻都保持最新狀態(tài)。通過事件處理瓶殃,批處理或其他更新機(jī)制充包,這些依賴會在一定時(shí)間內(nèi)得以解決。但在每個(gè)事務(wù)完成時(shí)遥椿,AGGREGATE內(nèi)部所應(yīng)用的固定規(guī)則必須得到滿足基矮。為了實(shí)現(xiàn)這個(gè)概念上的AGGREGATE,需要對所有事務(wù)應(yīng)用一組規(guī)則:

□ 根ENTITY具有全局標(biāo)識冠场,它最終負(fù)責(zé)檢查固定規(guī)則家浇。

□ 根ENTITY具有全局標(biāo)識。邊界內(nèi)的ENTITY具有本地標(biāo)識碴裙,這些標(biāo)識只在AGGREGATE內(nèi)部才是唯一的钢悲。

□ AGGREGATE外部的對象不能引用除根ENTITY之外的任何內(nèi)部對象点额。根ENTITY可以把對內(nèi)部ENTITY的引用傳遞給它們,但這些對象只能臨時(shí)使用這些引用莺琳,而不能保持引用还棱。根可以把一個(gè)VALUE OBJECT的副本傳遞給另外一個(gè)對象,而不必關(guān)心它發(fā)生什么變化惭等,因?yàn)樗皇且粋€(gè)VALUE珍手,不再與AGGREGATE有任何關(guān)聯(lián)。

□ 作為上一條規(guī)則的推論辞做,只有AGGREGATE的根才能直接通過數(shù)據(jù)庫查詢獲取琳要。所有其他對象必須通過遍歷關(guān)聯(lián)來發(fā)現(xiàn)。

□ AGGREGATE內(nèi)部的對象可以保持對其他AGGREGATE根的引用凭豪。

□ 刪除操作必須一次刪除AGGREGATE邊界之內(nèi)的所有對象焙蹭。(利用垃圾回收機(jī)制,這很容易做到嫂伞。由于除了根以外的其他對象都沒有外部引用孔厉,因此刪除了根以后,其他對象均會被回收帖努。)

□ 當(dāng)提交對AGGREGATE邊界內(nèi)部的任何對象的修改時(shí)撰豺,整個(gè)AGGREGATE的所有固定規(guī)則都必須滿足。

本地標(biāo)識與全局標(biāo)識及對象引用??

我們應(yīng)該將ENTITY和VALUE OBJECT分門類別地聚集到AGGREGATE中拼余,并定義每個(gè)AGGREGATE的邊界污桦。在每個(gè)AGGREGATE中,選擇一個(gè)ENTITY作為根匙监,并通過根來控制對邊界內(nèi)其他對象的所有訪問凡橱。只允許外部對象保持對根對象的引用。對內(nèi)部成員的臨時(shí)引用可以被傳遞出去亭姥,但僅在一次操作中有效稼钩。由于根控制訪問,因此不能繞過它來修改內(nèi)部對象达罗。這種設(shè)計(jì)有利于確保AGGREAGATE中的對象滿足所有固定規(guī)則坝撑,也可以確保在任何狀態(tài)變化時(shí)AGGREGATE作為一個(gè)整體滿足固定規(guī)則。

模式:FACTORY

與FACTORY的基本交互??

當(dāng)創(chuàng)建一個(gè)對象或創(chuàng)建整個(gè)AGGREGATE時(shí)粮揉,如果創(chuàng)建工作很復(fù)雜巡李,或者暴露了過多的內(nèi)部結(jié)果,則可以使用FACTORY進(jìn)行封裝扶认。

對象的創(chuàng)建本身可以是一個(gè)主要操作侨拦,但被創(chuàng)建的對象并不適合承擔(dān)復(fù)雜的裝配操作。將這些職責(zé)混在一起可能產(chǎn)生難以理解的拙劣設(shè)計(jì)蝠引。讓客戶直接負(fù)責(zé)創(chuàng)建對象又會使客戶的設(shè)計(jì)陷入混亂阳谍,并且破壞被裝配對象或AGGREGATE的封裝蛀柴,而且導(dǎo)致客戶與被創(chuàng)建對象的實(shí)現(xiàn)之間產(chǎn)生過于緊密的耦合螃概。

因此:應(yīng)該講創(chuàng)建復(fù)雜對象的實(shí)例和AGGREGATE的職責(zé)轉(zhuǎn)移給單獨(dú)的對象矫夯,這個(gè)對象本身可能沒有承擔(dān)領(lǐng)域模型中的職責(zé),但它仍是領(lǐng)域設(shè)計(jì)的一部分吊洼。提供一個(gè)封裝所有復(fù)雜裝配操作的接口训貌,而且這個(gè)接口不需要客戶引用要被實(shí)例化的對象的具體類。在創(chuàng)建AGGREGATE時(shí)要把它作為一個(gè)整體冒窍,并確保它滿足固定規(guī)則递沪。

模式:REPOSITORY

REPOSITORY為客戶執(zhí)行一個(gè)搜索??

在所有持久化對象中,有一小部分必須通過基于對象屬性的搜索來全局訪問综液。當(dāng)很難通過遍歷方式來訪問某些AGGREGATE根的時(shí)候款慨,就需要使用這種訪問方式。它們通常是ENTITY谬莹,有時(shí)是具有復(fù)雜內(nèi)部結(jié)構(gòu)的VALUE OBJECT檩奠,還可能是枚舉VALUE。而其他對象則不宜使用這種方式附帽,因?yàn)檫@會混淆它們之間的重要區(qū)別埠戳。隨意的數(shù)據(jù)庫查詢會破壞領(lǐng)域?qū)ο蟮姆庋b和AGGREGATE。技術(shù)基礎(chǔ)設(shè)施和數(shù)據(jù)庫訪問機(jī)制的暴露會增加客戶的復(fù)雜度蕉扮,并妨礙模型驅(qū)動的設(shè)計(jì)整胃。

REPOSITORY是一個(gè)簡單的概念框架,它可用來封裝這些解決方案喳钟,并將我們的注意力重新拉回到模型上屁使。REPOSITORY將某種類型的所有對象表示為一個(gè)概念集合(通常是模擬的)。它的行為類似于集合(collection)奔则,只是具有更復(fù)雜的查詢功能蛮寂。

因此:為每種需要全局訪問的對象類型創(chuàng)建一個(gè)對象,這個(gè)對象相當(dāng)于該類型的所有對象在內(nèi)存中的一個(gè)集合的“替身”应狱。通過一個(gè)眾所周知的全局接口來提供訪問共郭。提供添加和刪除對象的方法,用這些方法來封裝在數(shù)據(jù)存儲中實(shí)際插入或刪除數(shù)據(jù)的操作疾呻。提供根據(jù)具體條件來挑選對象的方法除嘹,并返回屬性值滿足查詢條件的對象或?qū)ο蠹希ㄋ祷氐膶ο笫峭耆珜?shí)例化的),從而將實(shí)際的存儲和查詢技術(shù)封裝起來岸蜗。只為那些確實(shí)需要直接訪問的AGGREGATE根提供REPOSITORY尉咕。讓客戶始終聚焦于模型,而將所有對象的存儲和訪問操作交給REPOSITORY來完成璃岳。

FACTORY與REPOSITORY的關(guān)系是:FACTORY負(fù)責(zé)處理對象生命周期的開始年缎,而REPOSITORY幫助管理生命周期的中間和結(jié)束悔捶。從領(lǐng)域驅(qū)動設(shè)計(jì)的角度來看,F(xiàn)ACTORY和REPOSITORY具有完全不同的職責(zé)单芜。FACTORY負(fù)責(zé)制造新對象蜕该,而REPOSITORY負(fù)責(zé)查找已有對象。

【學(xué)習(xí)心得】:有時(shí)候?qū)W習(xí)上的困難不是因?yàn)樽约旱睦斫饽芰Σ钪摒侨狈σ欢ǖ幕A(chǔ)溝通語言堂淡。急于求成和半路出家的問題就在于基礎(chǔ)的不扎實(shí),也就是我們所說的野路子扒腕。我曾經(jīng)也會認(rèn)為用到了再來學(xué)绢淀,這都是技術(shù)圈子的一個(gè)悖論。就好像等自己需要用錢了再來理財(cái)一樣可笑瘾腰。

第7章:使用語言:一個(gè)擴(kuò)展的示例

略皆的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蹋盆,隨后出現(xiàn)的幾起案子费薄,更是在濱河造成了極大的恐慌,老刑警劉巖怪嫌,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件义锥,死亡現(xiàn)場離奇詭異,居然都是意外死亡岩灭,警方通過查閱死者的電腦和手機(jī)拌倍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來噪径,“玉大人柱恤,你說我怎么就攤上這事≌野” “怎么了梗顺?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長车摄。 經(jīng)常有香客問我寺谤,道長,這世上最難降的妖魔是什么吮播? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任变屁,我火速辦了婚禮,結(jié)果婚禮上意狠,老公的妹妹穿的比我還像新娘粟关。我一直安慰自己,他們只是感情好环戈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布闷板。 她就那樣靜靜地躺著澎灸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪遮晚。 梳的紋絲不亂的頭發(fā)上性昭,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音鹏漆,去河邊找鬼巩梢。 笑死创泄,一個(gè)胖子當(dāng)著我的面吹牛艺玲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鞠抑,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饭聚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搁拙?” 一聲冷哼從身側(cè)響起秒梳,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎箕速,沒想到半個(gè)月后酪碘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盐茎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年兴垦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片字柠。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡探越,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窑业,到底是詐尸還是另有隱情钦幔,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布常柄,位于F島的核電站鲤氢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏西潘。R本人自食惡果不足惜卷玉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秸架。 院中可真熱鬧揍庄,春花似錦、人聲如沸东抹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至食茎,卻和暖如春蒂破,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背别渔。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工附迷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哎媚。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓喇伯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拨与。 傳聞我的和親對象是個(gè)殘疾皇子稻据,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

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