學(xué)習(xí)資源來(lái)自Gitchat上張逸的《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)實(shí)踐》
中間有兩篇介紹運(yùn)用領(lǐng)域場(chǎng)景分析提煉領(lǐng)域知識(shí),以及一篇建立統(tǒng)一語(yǔ)言迄沫,沒(méi)做記錄,主要是想keep it simple卦方,這三篇都是需求分析相關(guān)的內(nèi)容羊瘩,開(kāi)發(fā)人員不需要掌握,需求人員靠這三篇也掌握不了啥盼砍,所以我認(rèn)為知道意思是要通過(guò)科學(xué)的方法從業(yè)務(wù)需求中提煉領(lǐng)域知識(shí),并建立統(tǒng)一語(yǔ)言即可睬捶,具體怎么做就交給專業(yè)的人吧近刘,因此沒(méi)必要記錄觉渴。
在日常的對(duì)話中,說(shuō)話的語(yǔ)氣與語(yǔ)境就是幫助我們理解對(duì)話含義的上下文(Context)座韵。當(dāng)我們?cè)诶斫庀到y(tǒng)的領(lǐng)域需求時(shí)誉碴,同樣需要借助這樣的上下文,而限界上下文的含義就是用一個(gè)清晰可見(jiàn)的邊界(Bounded)將這個(gè)上下文勾勒出來(lái),如此就能在自己的邊界內(nèi)維持領(lǐng)域模型的一致性與完整性旨涝。Eric Evans 用細(xì)胞來(lái)形容限界上下文,因?yàn)椤凹?xì)胞之所以能夠存在慨默,是因?yàn)榧?xì)胞膜限定了什么在細(xì)胞內(nèi)厦取,什么在細(xì)胞外管搪,并且確定了什么物質(zhì)可以通過(guò)細(xì)胞膜更鲁。”這里漂坏,細(xì)胞代表上下文顶别,而細(xì)胞膜代表了包裹上下文的邊界驯绎。
因此谋旦,若要理解限界上下文蛤织,就需要從 Bounded 與 Context 這兩個(gè)單詞的含義來(lái)理解指蚜,Context 表現(xiàn)了業(yè)務(wù)流程的場(chǎng)景片段。整個(gè)業(yè)務(wù)流程由諸多具有時(shí)序的活動(dòng)組成绽媒,隨著流程的進(jìn)行,不同的活動(dòng)需要不同的角色參與囤热,并導(dǎo)致上下文因?yàn)槟硞€(gè)活動(dòng)的產(chǎn)生隨之發(fā)生切換旁蔼。因而棺聊,上下文(Context)其實(shí)是動(dòng)態(tài)的業(yè)務(wù)流程被邊界(Bounded)靜態(tài)切分的產(chǎn)物贞谓。
例如裸弦,我在飛機(jī)上,忽然想起給客戶提供的咨詢方案還需要完善耐亏,于是我拿出電腦广辰,在一萬(wàn)米高空上繼續(xù)思考我的領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)方案择吊,這時(shí)的我雖然還在飛機(jī)上几睛,身份卻切換成了一名咨詢師(Consultant)粤攒。當(dāng)我作為乘客乘坐出租車(chē)前往酒店夯接,并到前臺(tái)辦理入住手續(xù)時(shí),我又“撕下了乘客的面具”晴弃,搖身一變成為了酒店的賓客(Guest)。次日早晨际邻,我在酒店餐廳用完早餐后世曾,離開(kāi)酒店前往客戶公司轮听。隨著我走出酒店這個(gè)活動(dòng)的發(fā)生,酒店上下文又切換回交通出行蕊程。當(dāng)我到達(dá)客戶所在地時(shí),面對(duì)客戶驹暑,我開(kāi)始以一名咨詢師身份與客戶團(tuán)隊(duì)交談,了解他們的咨詢目標(biāo)與現(xiàn)有痛點(diǎn)京办。我制定咨詢計(jì)劃與方案惭婿,并與客戶一起評(píng)審咨詢方案叶雹,這時(shí)的上下文就切換為咨詢工作了折晦。巧合的是,無(wú)論是交通出行還是酒店谦炒,都需要支付費(fèi)用宁改,支付的費(fèi)用雖然不同魂莫,支付的行為也有所差別,需要用到的領(lǐng)域知識(shí)卻是相同的鲸沮,因此這個(gè)活動(dòng)又可以歸為支付上下文锅论。
上下文在流程中的切換猶如電影畫(huà)面的場(chǎng)景切換最易,相同的人物扮演了不同的角色,在不同的上下文參與了不同的活動(dòng)剔猿。由于活動(dòng)的目標(biāo)發(fā)生了改變归敬,履行的職責(zé)亦有所不同鄙早,上述場(chǎng)景如下圖所示:
整個(gè)業(yè)務(wù)流程由諸多活動(dòng)(Actions)組成舱污,參與這些活動(dòng)的有不同的角色弥虐。在每一個(gè)上下文中霜瘪,角色與角色之間通過(guò)活動(dòng)產(chǎn)生協(xié)作,以滿足業(yè)務(wù)流程的需求丧失。這些活動(dòng)是分散的布讹,活動(dòng)的目標(biāo)也不相同训堆,但在同一個(gè)上下文中坑鱼,這些活動(dòng)卻是為同一個(gè)目標(biāo)提供服務(wù)。
因此呼股,在理解限界上下文時(shí),我們需要重視幾個(gè)關(guān)鍵點(diǎn):
- 知識(shí):不同的限界上下文需要的領(lǐng)域知識(shí)是不相同的彭谁,這實(shí)則就是業(yè)務(wù)相關(guān)性缠局,參與到限界上下文中的活動(dòng)也與“知識(shí)”有關(guān)。如果執(zhí)行該活動(dòng)卻不具備對(duì)應(yīng)知識(shí)读处,則說(shuō)明對(duì)活動(dòng)的分配不合理罚舱;如果該活動(dòng)的目標(biāo)與該限界上下文保持一致馆匿,卻缺乏相應(yīng)知識(shí)燥滑,則說(shuō)明該活動(dòng)需要與別的限界上下文協(xié)作铭拧。
- 角色:一定要深入思考參與到這個(gè)上下文的對(duì)象究竟扮演了什么樣的角色搀菩,以及角色與角色在這個(gè)上下文中是如何協(xié)作的肪跋。
- 邊界:限界上下文按照不同關(guān)注點(diǎn)進(jìn)行分離州既,各自的邊界則根據(jù)耦合關(guān)系的強(qiáng)弱來(lái)確定萝映,越是關(guān)系最弱的地方序臂,越是需要?jiǎng)澏ㄟ吔纭?/li>
我們需要根據(jù)業(yè)務(wù)相關(guān)性、耦合的強(qiáng)弱程度咸灿、分離的關(guān)注點(diǎn)對(duì)這些活動(dòng)進(jìn)行歸類(lèi)析显,找到不同類(lèi)別之間存在的邊界谷异,這就是限界上下文的含義锦聊。上下文(Context)是業(yè)務(wù)目標(biāo)孔庭,限界(Bounded)則是保護(hù)和隔離上下文的邊界圆到,避免業(yè)務(wù)目標(biāo)的不單一而帶來(lái)的混亂與概念的不一致
觀察角度的不同,限界上下文劃定的邊界也有所不同马绝。大體可以分為如下三個(gè)方面:
- 領(lǐng)域邏輯層面:限界上下文確定了領(lǐng)域模型的業(yè)務(wù)邊界挣菲,維護(hù)了模型的完整性與一致性,從而降低系統(tǒng)的業(yè)務(wù)復(fù)雜度椭赋。
- 團(tuán)隊(duì)合作層面:限界上下文確定了開(kāi)發(fā)團(tuán)隊(duì)的工作邊界哪怔,建立了團(tuán)隊(duì)之間的合作模式向抢,避免團(tuán)隊(duì)之間的溝通變得混亂笋额,從而降低系統(tǒng)的管理復(fù)雜度兄猩。
- 技術(shù)實(shí)現(xiàn)層面:限界上下文確定了系統(tǒng)架構(gòu)的應(yīng)用邊界,保證了系統(tǒng)層和上下文領(lǐng)域?qū)痈髯缘囊恢滦酝眩⒘松舷挛闹g的集成方式讶迁,從而降低系統(tǒng)的技術(shù)復(fù)雜度连茧。
這三種邊界體現(xiàn)了限界上下文對(duì)不同邊界的控制力。業(yè)務(wù)邊界是對(duì)領(lǐng)域模型的控制巍糯,工作邊界是對(duì)開(kāi)發(fā)協(xié)作的控制啸驯,應(yīng)用邊界是對(duì)技術(shù)風(fēng)險(xiǎn)的控制。引入限界上下文的目的祟峦,其實(shí)不在于如何劃分邊界罚斗,而在于如何控制邊界。
限界上下文是“分而治之”架構(gòu)原則的體現(xiàn)宅楞,我們引入它的目的其實(shí)為了控制(應(yīng)對(duì))軟件的復(fù)雜度针姿,它并非某種固定的設(shè)計(jì)單元,我們不能說(shuō)它就是模塊厌衙、服務(wù)或組件距淫,而是通過(guò)它來(lái)幫助我們做出高內(nèi)聚低耦合的設(shè)計(jì)拐揭。只要遵循了這個(gè)設(shè)計(jì)家肯,則限界上下文就可能成為模塊换棚、服務(wù)或組件歹茶。
這里禽作,要提到一個(gè)重要的概念爆侣,就是“自治”,拋開(kāi)模塊、服務(wù)或組件對(duì)你的影響,請(qǐng)大家先把限界上下文看做是一個(gè)“自治”的單元嗤堰。所謂“自治”就是滿足四個(gè)特征:最小完備离唬、穩(wěn)定空間裸诽、自我履行、獨(dú)立進(jìn)化往弓。
最小完備是實(shí)現(xiàn)“自治”的基本條件。所謂“完備”准给,是指自治單元履行的職責(zé)是完整的畔规,無(wú)需針對(duì)自己的信息去求助別的自治單元畜埋,這就避免了不必要的依賴關(guān)系咖祭。而“最小完備”則進(jìn)一步地限制了完備的范圍硬鞍,避免將不必要的職責(zé)被錯(cuò)誤地添加到該自治單元上糖儡。對(duì)于限界上下文而言,就是要根據(jù)業(yè)務(wù)價(jià)值的完整性進(jìn)行設(shè)計(jì)。例如浓利,對(duì)于支付上下文,其業(yè)務(wù)價(jià)值就是“安全地完成在線支付業(yè)務(wù)”驾凶,那么在確定限界上下文的時(shí)候,就應(yīng)該以完成該業(yè)務(wù)價(jià)值的最小功能集為設(shè)計(jì)邊界翰萨。
自我履行意味著由自治單元自身決定要做什么黄绩。從擬人的角度來(lái)思考粤蝎,就是這些自治單元能夠?qū)ν獠空?qǐng)求做出符合自身利益的明智判斷碑宴,是否應(yīng)該履行該職責(zé)榜跌,由限界上下文擁有的信息來(lái)決定番刊。例如佳晶,可以站在自治單元的角度去思考:“如果我擁有了這些信息逸贾,我究竟應(yīng)該履行哪些職責(zé)?”這些職責(zé)屬于當(dāng)前上下文的活動(dòng)范圍撞鹉,一旦超出享郊,就該毫不猶豫地將不屬于該范圍的請(qǐng)求轉(zhuǎn)交給別的上下文又活。例如,在當(dāng)訂單上下文履行了驗(yàn)證訂單的職責(zé)之后,需要執(zhí)行支付活動(dòng)時(shí),由于與支付相關(guān)的業(yè)務(wù)行為要操作的信息已經(jīng)超出了訂單上下文的范疇,就應(yīng)該將該職責(zé)轉(zhuǎn)移到支付上下文。自我履行其實(shí)意味著對(duì)知識(shí)的掌握耍攘,為避免風(fēng)險(xiǎn)榕栏,你要履行的職責(zé)一定是你掌握的知識(shí)范疇之內(nèi)。
穩(wěn)定空間指的是減少外界變化對(duì)限界上下文內(nèi)部的影響蕾各。自治的設(shè)計(jì)就是要?jiǎng)澏ǚ謱僮约旱姆€(wěn)定空間扒磁,讓自治單元擁有空間內(nèi)的掌控權(quán),保持空間的私密性式曲,開(kāi)放空間接口應(yīng)對(duì)外部的請(qǐng)求妨托。劃分自治空間,需要找到限界上下文之間的間隙處检访,然后依勢(shì)而為始鱼,沿著間隙方向順勢(shì)劃分,而所謂“間隙”脆贵,其實(shí)就是依賴最為薄弱之處医清。例如,在電商系統(tǒng)中卖氨,管理商品上架会烙、下架與評(píng)價(jià)商品都與商品直接相關(guān),但顯然評(píng)價(jià)商品與商品的依賴關(guān)系更弱筒捺。倘若需要分解限界上下文柏腻,保證上下文的穩(wěn)定性,就可以將評(píng)價(jià)商品的職責(zé)從商品上下文中分離出去系吭,但卻不能分離商品上架和下架功能五嫂。穩(wěn)定空間符合開(kāi)放封閉原則(OCP),即對(duì)修改是封閉的肯尺,對(duì)擴(kuò)展是開(kāi)放的沃缘,該原則其實(shí)體現(xiàn)了一個(gè)單元的封閉空間與開(kāi)放空間。封閉空間體現(xiàn)為對(duì)細(xì)節(jié)的封裝與隱藏则吟,開(kāi)放空間體現(xiàn)為對(duì)共性特征的抽象與統(tǒng)一槐臀,二者共同確保了整個(gè)空間的穩(wěn)定。
獨(dú)立進(jìn)化與穩(wěn)定空間剛好相反氓仲,指的是減少限界上下文的變化對(duì)外界的影響水慨。如果借用限界上下文的上下游關(guān)系來(lái)闡釋得糜,則穩(wěn)定空間寓意下游限界上下文,無(wú)論上游怎么變晰洒,我自巋然不動(dòng)朝抖;獨(dú)立進(jìn)化寓意上游限界上下文,無(wú)論下游有多少欢顷,我凌寒獨(dú)自開(kāi)槽棍。實(shí)現(xiàn)上看捉蚤,要做到獨(dú)立進(jìn)化抬驴,就必須保證對(duì)外公開(kāi)接口的穩(wěn)定性,因?yàn)檫@些接口往往被眾多消費(fèi)者使用缆巧,一旦修改布持,就會(huì)牽一發(fā)而動(dòng)全身。一個(gè)獨(dú)立進(jìn)化的限界上下文陕悬,需要接口設(shè)計(jì)良好题暖,符合標(biāo)準(zhǔn)規(guī)范,并在版本上考慮了兼容與演化捉超。
自治的這四個(gè)要素是相輔相成的胧卤。最小完備意味著職責(zé)是完備的,從而減少了變化的可能拼岳;自我履行意味著自治單元能夠智能地判斷行為是否應(yīng)該由其履行枝誊,當(dāng)變化發(fā)生時(shí),也能聰明審慎地做出合理判斷惜纸;穩(wěn)定空間通過(guò)隱藏細(xì)節(jié)和開(kāi)放抽象接口來(lái)封裝變化叶撒;獨(dú)立進(jìn)化則通過(guò)約束接口的規(guī)范與版本保證內(nèi)部實(shí)現(xiàn)的演化乃至于對(duì)實(shí)現(xiàn)進(jìn)行全面地替換。最小完備是基礎(chǔ)耐版,只有賦予了限界上下文足夠的信息祠够,才能保證它的自我履行。穩(wěn)定空間與獨(dú)立進(jìn)化則一個(gè)對(duì)內(nèi)一個(gè)對(duì)外粪牲,是對(duì)變化的有效應(yīng)對(duì)古瓤,而它們又是通過(guò)最小完備和自我履行來(lái)保障限界上下文受到變化的影響最小。
這四個(gè)要素又是高內(nèi)聚低耦合思想的體現(xiàn)腺阳。我們需要根據(jù)業(yè)務(wù)關(guān)注點(diǎn)和技術(shù)關(guān)注點(diǎn)落君,盡可能將強(qiáng)相關(guān)性的內(nèi)容放到同一個(gè)限界上下文中,同時(shí)降低限界上下文之間的耦合舌狗。對(duì)于整個(gè)系統(tǒng)架構(gòu)而言叽奥,不同的限界上下文可以采用不同的架構(gòu)風(fēng)格與技術(shù)決策,而在每個(gè)限界上下文內(nèi)部保持自己的技術(shù)獨(dú)立性與一致性痛侍。由于限界上下文邊界對(duì)技術(shù)實(shí)現(xiàn)的隔離朝氓,不同限界上下文內(nèi)部實(shí)現(xiàn)的多樣性并不會(huì)影響整體架構(gòu)的一致性魔市。
個(gè)人寄語(yǔ):個(gè)人認(rèn)為知道限界上下文就是系統(tǒng)拆分解耦和的最小單位就好了,至于粒度嘛赵哲,感覺(jué)還是by experience待德,這些概念在實(shí)踐中感覺(jué)沒(méi)什么大的卵用。