重慶分公司,新征程啟航
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊(cè)、服務(wù)器等服務(wù)
為企業(yè)提供網(wǎng)站建設(shè)、域名注冊(cè)、服務(wù)器等服務(wù)
本書是Eric Evans對(duì)他自己寫的《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)-軟件核心復(fù)雜性應(yīng)對(duì)之道》的一本字典式的參考書,可用于快速查找《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》中的諸多概念及其簡明解釋。
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比雙牌網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式雙牌網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋雙牌地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
其它本系列其它文章地址:
[譯文]Domain Driven Design Reference(一)—— 前言
[譯文]Domain Driven Design Reference(二)—— 讓模型起作用
[譯文]Domain Driven Design Reference(三)—— 模型驅(qū)動(dòng)設(shè)計(jì)的構(gòu)建模塊
[譯文]Domain Driven Design Reference(四)—— 柔性設(shè)計(jì)
[譯文]Domain Driven Design Reference(五)—— 為戰(zhàn)略設(shè)計(jì)的上下文映射
對(duì)一個(gè)特定模型的定義和適用范圍(通常是一個(gè)子系統(tǒng),或特定團(tuán)隊(duì)的工作)的描述。
兩個(gè)組之間的關(guān)系是“上游”小組的行為影響“下游”小組的項(xiàng)目成功。但下游的行為并不會(huì)顯著影響上游項(xiàng)目。(例如,如果兩個(gè)城市沿著同一條河流,上游城市的污染主要影響下游城市。)
上游團(tuán)隊(duì)可以獨(dú)立于下游團(tuán)隊(duì)的命運(yùn)而取得成功。
必須在不同的上下文中交付兩個(gè)軟件開發(fā)項(xiàng)目以使其中任何一個(gè)被認(rèn)為是成功的情況。(當(dāng)兩個(gè)系統(tǒng)各自依賴另一個(gè)系統(tǒng)的信息或功能時(shí),我們通常會(huì)盡量避免將看到的項(xiàng)目構(gòu)建成相互依賴的。 然而,也有一些相互依賴的項(xiàng)目,系統(tǒng)依賴性只向一個(gè)方向發(fā)展。當(dāng)依賴系統(tǒng)沒有其它的系統(tǒng)與該系統(tǒng)的集成時(shí),它幾乎沒有任何價(jià)值,或許因?yàn)檫@是唯一一個(gè)使用它的地方,那么未能提供依賴系統(tǒng)就會(huì)導(dǎo)致兩個(gè)項(xiàng)目都失敗。)
一個(gè)理想中的軟件開發(fā)上下文,在其它上下文中的開發(fā)工作是成功或失敗對(duì)其自己的交付沒有什么影響。
為了策劃戰(zhàn)略,我們需要一個(gè)現(xiàn)實(shí)的,大范圍的模型開發(fā)視圖,擴(kuò)展到我們的項(xiàng)目和我們整合的其他項(xiàng)目。
在沒有全局視圖的情況下,個(gè)別限界上下文會(huì)遺留下一些問題。其他模型的上下文可能仍然是模糊不清的。
其他團(tuán)隊(duì)的人不會(huì)意識(shí)到上下文的界限,并且會(huì)在不知不覺中做出一些模糊邊緣或使內(nèi)部連接復(fù)雜化的改變。當(dāng)連接必須在不同的上下文中進(jìn)行時(shí),它們往往會(huì)相互×××。
即使邊界清晰,與其他上下文的關(guān)系也會(huì)限制模型的性質(zhì)或可行的變化速度。這些制約因素需要通過非技術(shù)渠道表現(xiàn)出來,有時(shí)很難與他們正在影響的設(shè)計(jì)決策聯(lián)系起來。
因此:
識(shí)別項(xiàng)目中正在使用的每個(gè)模型并定義它的限界上下文。這包括非面向?qū)ο笞酉到y(tǒng)的隱式模型。給每個(gè)限界上下文命名,并且使其名稱成為通用語言的一部分。
描述模型之間的聯(lián)系點(diǎn),列出對(duì)任何交互的明確翻譯,突出任何共享、隔離機(jī)制和影響程度。
映射現(xiàn)有的領(lǐng)域范圍。稍后再進(jìn)行轉(zhuǎn)換。
這張映射圖可以成為實(shí)際設(shè)計(jì)策略的基礎(chǔ)。
在接下來的幾頁中,關(guān)系的描述會(huì)變得更加具體,在限界上下文之間有一組通用的關(guān)系模式。
當(dāng)兩個(gè)上下文中的團(tuán)隊(duì)共同成功或失敗時(shí),通常會(huì)出現(xiàn)合作關(guān)系。
在相互獨(dú)立的上下文中,相互依賴的子系統(tǒng)缺少協(xié)作會(huì)導(dǎo)致兩個(gè)項(xiàng)目的交付失敗。一個(gè)系統(tǒng)缺失的一個(gè)關(guān)鍵特性可能會(huì)使另一個(gè)系統(tǒng)無法交付。不符合其他子系統(tǒng)開發(fā)人員期望的接口可能導(dǎo)致集成失敗。一個(gè)相互約定的接口可能會(huì)變得過于別扭,以致于減慢了客戶端系統(tǒng)的開發(fā)速度,或者很難實(shí)現(xiàn),從而減慢了服務(wù)端子系統(tǒng)的開發(fā)速度。失敗帶來了兩個(gè)項(xiàng)目的失利。
因此:
如果兩個(gè)上下文中的任何一個(gè)開發(fā)失敗都將導(dǎo)致兩個(gè)上下文的交付一起失敗,則在負(fù)責(zé)這兩個(gè)上下文的小組之間建立合作關(guān)系。制定協(xié)調(diào)發(fā)展和聯(lián)合管理一體化的過程。
團(tuán)隊(duì)必須在其接口的演進(jìn)上進(jìn)行協(xié)作,以適應(yīng)這兩個(gè)系統(tǒng)的開發(fā)需求。應(yīng)該安排相互依賴的feature,以便它們?cè)谕话姹局型瓿伞?/strong>
大多數(shù)情況下,開發(fā)人員不需要詳細(xì)了解其他子系統(tǒng)的模型,但他們必須協(xié)調(diào)他們的項(xiàng)目計(jì)劃。當(dāng)一個(gè)上下文中的開發(fā)遇到障礙時(shí),則需要聯(lián)合研究這個(gè)問題,以找到一種緊急的設(shè)計(jì)解決方案,而不會(huì)過分地?fù)p害任何一方。
此外,還需要一個(gè)清晰的過程來管理集成。例如,可以定義一個(gè)特殊的測(cè)試套件,以證明接口符合客戶端系統(tǒng)的期望,它可以作為服務(wù)器系統(tǒng)上持續(xù)集成的一部分運(yùn)行。
共享模型和相關(guān)代碼的一部分是非常密切的相互依賴關(guān)系,它能夠加快設(shè)計(jì)工作或者破壞這些共享的東西。
當(dāng)功能集成受到限制時(shí),大型上下文的持續(xù)集成的開銷可能會(huì)被認(rèn)為太高。當(dāng)團(tuán)隊(duì)沒有足夠的技能或組織架構(gòu)來維持持續(xù)集成,或者單個(gè)團(tuán)隊(duì)的規(guī)模太大而笨拙時(shí),這種情況可能尤為明顯。因此,可以定義獨(dú)立的限界上下文,并形成多個(gè)團(tuán)隊(duì)。
一旦獨(dú)立的、不協(xié)調(diào)的團(tuán)隊(duì)在密切相關(guān)的應(yīng)用程序上工作,可能會(huì)向前推進(jìn)一段時(shí)間,但是他們生產(chǎn)的產(chǎn)品可能不適合在一起。即使是合作伙伴團(tuán)隊(duì)最終也會(huì)花費(fèi)大量精力在翻譯層和改造上,同時(shí)重復(fù)這些工作并失去通用語言的好處。
因此:
用明確的邊界指定團(tuán)隊(duì)同意分享的領(lǐng)域模型的一部分子集。保持這個(gè)內(nèi)核盡可能的小。
在這個(gè)邊界內(nèi),包括模型的子集,代碼的子集,或者與該模型的部分相關(guān)聯(lián)的數(shù)據(jù)庫設(shè)計(jì)。這種顯式共享的內(nèi)容具有特殊的地位,在未與其他團(tuán)隊(duì)協(xié)商的情況下不應(yīng)改變。
定義一個(gè)持續(xù)集成過程,以保持內(nèi)核模型的緊湊性,并與團(tuán)隊(duì)的通用語言保持一致。經(jīng)常其整合功能系統(tǒng),雖然比團(tuán)隊(duì)中持續(xù)集成的次數(shù)要少一些。
當(dāng)兩個(gè)團(tuán)隊(duì)處于上下游關(guān)系時(shí),上游團(tuán)隊(duì)可能獨(dú)立于下游團(tuán)隊(duì)的命運(yùn)而取得成功,下游的需求將以各種各樣的方式得到解決,并帶來廣泛的負(fù)面后果。
下游的團(tuán)隊(duì)可能是無助的,受上游優(yōu)先級(jí)的擺布。與此同時(shí),上游團(tuán)隊(duì)可能會(huì)收到抑制,擔(dān)心會(huì)破壞下游系統(tǒng)。擁有復(fù)雜審批流程的繁瑣的變更請(qǐng)求過程并沒有改善下游團(tuán)隊(duì)的問題。如果下游團(tuán)隊(duì)對(duì)變更擁有否決權(quán),上游團(tuán)隊(duì)的自由發(fā)展就會(huì)停止。
因此:
在兩個(gè)團(tuán)隊(duì)之間建立清晰的客戶/供應(yīng)商關(guān)系,意味著將下游優(yōu)先因素放到上游的規(guī)劃中。為下游需求進(jìn)行談判和預(yù)算任務(wù),以便每個(gè)人都了解承諾和時(shí)間表。
敏捷團(tuán)隊(duì)可以在規(guī)劃會(huì)議中讓下游團(tuán)隊(duì)扮演上游團(tuán)隊(duì)的客戶角色。聯(lián)合開發(fā)的自動(dòng)化驗(yàn)收測(cè)試可以驗(yàn)證來自上游的預(yù)期接口。將這些測(cè)試添加到上游團(tuán)隊(duì)的測(cè)試套件中,作為其持續(xù)集成的一部分,將使上游團(tuán)隊(duì)自由地進(jìn)行更改,而不必?fù)?dān)心下游的副作用。
當(dāng)兩個(gè)開發(fā)團(tuán)隊(duì)有一個(gè)上下游關(guān)系時(shí),上游沒有動(dòng)力為下游團(tuán)隊(duì)的需求提供幫助,下游團(tuán)隊(duì)就無能為力了。利他主義可能會(huì)促使上游開發(fā)者做出承諾,但它們不太可能實(shí)現(xiàn)。相信這些好意會(huì)導(dǎo)致下游團(tuán)隊(duì)基于無法獲得的特性來制定計(jì)劃。下游項(xiàng)目將被推遲,直到團(tuán)隊(duì)最終學(xué)會(huì)接受上游所提供的東西。針對(duì)下游團(tuán)隊(duì)的需求量身定制的接口是不太不可能的。
因此:
通過對(duì)上游團(tuán)隊(duì)的模型進(jìn)行嚴(yán)格的遵守,消除了限界上下文之間的轉(zhuǎn)換的復(fù)雜性。盡管這限制了下游設(shè)計(jì)人員的風(fēng)格,并且可能不會(huì)產(chǎn)生應(yīng)用程序的理想模型,但是選擇一致性極大地簡化了集成。此外,你將與上游團(tuán)隊(duì)共享一種通用語言。上游在駕駛員的位置上,所以讓他們的交流變得容易是件好事。利他主義可能足以讓他們與你分享信息。
當(dāng)與合作團(tuán)隊(duì)銜接良好設(shè)計(jì)的限界上下文時(shí),翻譯層可以是簡單的,甚至是優(yōu)雅的。但是,當(dāng)控制或通信不足以實(shí)現(xiàn)共享內(nèi)核、合作伙伴或客戶供應(yīng)商關(guān)系時(shí),轉(zhuǎn)換就變得更加復(fù)雜。翻譯層采用了一種更具防御性的語氣。
一個(gè)提供給上游系統(tǒng)的大型接口最終可能完全顛覆下游模型的意圖,從而使其被修改成以一種特別的方式來模仿其他系統(tǒng)的模型。遺留系統(tǒng)的模型通常是很薄弱的(如果不是大泥球的話),即使是明確設(shè)計(jì)的例外也可能不符合當(dāng)前項(xiàng)目的需求,這使得遵循上游模型變得不切實(shí)際。然而,這種集成對(duì)于下游項(xiàng)目可能非常有價(jià)值甚至是必需的。
因此:
作為下游客戶端,創(chuàng)建一個(gè)隔離層,根據(jù)您自己的領(lǐng)域模型,為系統(tǒng)提供上游系統(tǒng)的功能。該層通過其現(xiàn)有的接口與另一個(gè)系統(tǒng)進(jìn)行通信,只需要很少或不需要對(duì)其他系統(tǒng)進(jìn)行修改。在內(nèi)部,這一層在兩個(gè)模型之間需要單向或雙向轉(zhuǎn)換。
通常對(duì)于每個(gè)限界上下文,您將為每個(gè)部件定義一個(gè)翻譯層,您必須將其與上下文之外的組件集成在一起。在集成是一次性的情況下,為每個(gè)外部系統(tǒng)插入翻譯層的這種方法以最小的成本避免了模型的損壞。但是當(dāng)你發(fā)現(xiàn)你的子系統(tǒng)有更高的要求時(shí),你可能需要更靈活的方法。
當(dāng)一個(gè)子系統(tǒng)必須與許多其他的子系統(tǒng)集成時(shí),為每一個(gè)子系統(tǒng)定制一個(gè)翻譯對(duì)象可能會(huì)使團(tuán)隊(duì)陷入困境。有越來越多的維護(hù),越來越多的擔(dān)心什么時(shí)候會(huì)發(fā)生變化。
因此:
定義一個(gè)協(xié)議,將訪問您的子系統(tǒng)作為一組服務(wù)。 打開協(xié)議,使所有需要與您集成的人都可以使用它。增強(qiáng)和擴(kuò)展協(xié)議以處理新的集成需求,除非一個(gè)團(tuán)隊(duì)有特殊的需求。然后,使用一次性翻譯對(duì)象來增強(qiáng)該特殊情況的協(xié)議,以便共享協(xié)議能夠保持簡單和一致。
這將使服務(wù)提供者處于上游位置。每個(gè)客戶端都在下游,并且通常其中一些客戶端會(huì)遵守規(guī)定,有些客戶端會(huì)建立反腐層。具有開放主機(jī)服務(wù)的上下文可能與它的客戶端以外的上下文有任何關(guān)系。
兩個(gè)限界上下文模型之間的轉(zhuǎn)換需要一種通用語言。
直接轉(zhuǎn)換到現(xiàn)有的領(lǐng)域模型可能不是一個(gè)好的解決方案。這些模型可能過于復(fù)雜或被分解得很糟糕。也許他們說的是非法的。如果將其中一種用作數(shù)據(jù)交換語言,它實(shí)際上就會(huì)被凍結(jié),不能響應(yīng)新的開發(fā)需求。
因此:
使用一種文檔完整的公共語言,可以將必要的領(lǐng)域信息作為一種通用的通信媒介來表達(dá),并根據(jù)需要翻譯為該語言。
許多行業(yè)以數(shù)據(jù)交換標(biāo)準(zhǔn)的形式建立了公共語言。項(xiàng)目團(tuán)隊(duì)也開發(fā)自己的,在他們的組織內(nèi)使用。
公共語言通常與開放主機(jī)服務(wù)相結(jié)合。
在定義需求方面,我們必須冷酷無情。如果兩組功能之間沒有顯著的關(guān)系,它們可以完全相互分離。
整合總是代價(jià)很大的,有時(shí)候好處很小。
因此:
聲明一個(gè)限界上下文,使其與其他上下文完全沒有關(guān)聯(lián),允許開發(fā)人員在這個(gè)小范圍內(nèi)找到簡單的、專門的解決方案。
在我們調(diào)查現(xiàn)有的軟件系統(tǒng)時(shí),我們?cè)噲D了解不同的模型在定義的邊界內(nèi)是如何被應(yīng)用的,我們發(fā)現(xiàn)部分系統(tǒng)(通常是大型系統(tǒng)),模型是混合的,邊界是不一致的。
在沒有邊界的系統(tǒng)中,試圖描述模型的上下文邊界很容易陷入困境。
定義良好的上下文邊界作為知識(shí)選擇和社會(huì)力量的結(jié)果出現(xiàn)(盡管創(chuàng)建系統(tǒng)的人在當(dāng)時(shí)可能并不總是有意識(shí)地意識(shí)到這些原因)。當(dāng)這些因素缺失或消失時(shí),將多個(gè)概念系統(tǒng)混合在一起,使得定義和規(guī)則變得模棱兩可或相互矛盾。隨著特性的添加,系統(tǒng)是根據(jù)附加的邏輯來工作的。依賴關(guān)系縱橫交錯(cuò)。因果關(guān)系變得越來越難以追蹤。最終,軟件會(huì)凝結(jié)成一個(gè)大的泥球。
在某些情況下,大球泥實(shí)際上是非常實(shí)用的(正如Foote和Yoder的原文所描述的那樣),但它幾乎完全阻止了有用模型所需要的敏銳和精確性。
因此:
在整個(gè)混亂的周圍畫一個(gè)邊界,把它指定為一個(gè)大泥球。不要嘗試在此上下文中應(yīng)用復(fù)雜的建模。要警惕這種系統(tǒng)向其他上下文蔓延的趨勢(shì)。
(見http://www.laputan.org/mud/mud.html。Brian Foote和Joseph Yoder)
作者:Zachary_Fan
出處:http://www.cnblogs.com/Zachary-Fan/p/DDDReference5.html
如果你想及時(shí)得到個(gè)人自寫文章的消息推送,歡迎掃描下面的二維碼~。