本書是Eric Evans對他本身寫的《領域驅動設計-軟件核心複雜性應對之道》的一本字典式的參考書,可用於快速查找《領域驅動設計》中的諸多概念及其簡明解釋。html
其它本系列其它文章地址:數據庫
[譯文]Domain Driven Design Reference(一)—— 前言服務器
[譯文]Domain Driven Design Reference(二)—— 讓模型起做用架構
[譯文]Domain Driven Design Reference(三)—— 模型驅動設計的構建模塊數據庫設計
[譯文]Domain Driven Design Reference(四)—— 柔性設計測試
[譯文]Domain Driven Design Reference(五)—— 爲戰略設計的上下文映射 翻譯
對一個特定模型的定義和適用範圍(一般是一個子系統,或特定團隊的工做)的描述。設計
兩個組之間的關係是「上游」小組的行爲影響「下游」小組的項目成功。但下游的行爲並不會顯著影響上游項目。(例如,若是兩個城市沿着同一條河流,上游城市的污染主要影響下游城市。)cdn
上游團隊能夠獨立於下游團隊的命運而取得成功。htm
必須在不一樣的上下文中交付兩個軟件開發項目以使其中任何一個被認爲是成功的狀況。(當兩個系統各自依賴另外一個系統的信息或功能時,咱們一般會盡可能避免將看到的項目構建成相互依賴的。 然而,也有一些相互依賴的項目,系統依賴性只向一個方向發展。當依賴系統沒有其它的系統與該系統的集成時,它幾乎沒有任何價值,或許由於這是惟一一個使用它的地方,那麼未能提供依賴系統就會致使兩個項目都失敗。)
一個理想中的軟件開發上下文,在其它上下文中的開發工做是成功或失敗對其本身的交付沒有什麼影響。
爲了策劃戰略,咱們須要一個現實的,大範圍的模型開發視圖,擴展到咱們的項目和咱們整合的其餘項目。
在沒有全局視圖的狀況下,個別限界上下文會遺留下一些問題。其餘模型的上下文可能仍然是模糊不清的。
其餘團隊的人不會意識到上下文的界限,而且會在不知不覺中作出一些模糊邊緣或使內部鏈接複雜化的改變。當鏈接必須在不一樣的上下文中進行時,它們每每會相互滲透。
即便邊界清晰,與其餘上下文的關係也會限制模型的性質或可行的變化速度。這些制約因素須要經過非技術渠道表現出來,有時很難與他們正在影響的設計決策聯繫起來。
所以:
識別項目中正在使用的每一個模型並定義它的限界上下文。這包括非面向對象子系統的隱式模型。給每一個限界上下文命名,而且使其名稱成爲通用語言的一部分。
描述模型之間的聯繫點,列出對任何交互的明確翻譯,突出任何共享、隔離機制和影響程度。
映射現有的領域範圍。稍後再進行轉換。
這張映射圖能夠成爲實際設計策略的基礎。
在接下來的幾頁中,關係的描述會變得更加具體,在限界上下文之間有一組通用的關係模式。
當兩個上下文中的團隊共同成功或失敗時,一般會出現合做關係。
在相互獨立的上下文中,相互依賴的子系統缺乏協做會致使兩個項目的交付失敗。一個系統缺失的一個關鍵特性可能會使另外一個系統沒法交付。不符合其餘子系統開發人員指望的接口可能致使集成失敗。一個相互約定的接口可能會變得過於彆扭,以至於減慢了客戶端系統的開發速度,或者很難實現,從而減慢了服務端子系統的開發速度。失敗帶來了兩個項目的失利。
所以:
若是兩個上下文中的任何一個開發失敗都將致使兩個上下文的交付一塊兒失敗,則在負責這兩個上下文的小組之間創建合做關係。制定協調發展和聯合管理一體化的過程。
團隊必須在其接口的演進上進行協做,以適應這兩個系統的開發需求。應該安排相互依賴的feature,以便它們在同一版本中完成。
大多數狀況下,開發人員不須要詳細瞭解其餘子系統的模型,但他們必須協調他們的項目計劃。當一個上下文中的開發遇到障礙時,則須要聯合研究這個問題,以找到一種緊急的設計解決方案,而不會過度地損害任何一方。
此外,還須要一個清晰的過程來管理集成。例如,能夠定義一個特殊的測試套件,以證實接口符合客戶端系統的指望,它能夠做爲服務器系統上持續集成的一部分運行。
共享模型和相關代碼的一部分是很是密切的相互依賴關係,它可以加快設計工做或者破壞這些共享的東西。
當功能集成受到限制時,大型上下文的持續集成的開銷可能會被認爲過高。當團隊沒有足夠的技能或組織架構來維持持續集成,或者單個團隊的規模太大而笨拙時,這種狀況可能尤其明顯。所以,能夠定義獨立的限界上下文,並造成多個團隊。
一旦獨立的、不協調的團隊在密切相關的應用程序上工做,可能會向前推動一段時間,可是他們生產的產品可能不適合在一塊兒。即便是合做夥伴團隊最終也會花費大量精力在翻譯層和改造上,同時重複這些工做並失去通用語言的好處。
所以:
用明確的邊界指定團隊贊成分享的領域模型的一部分子集。保持這個內核儘量的小。
在這個邊界內,包括模型的子集,代碼的子集,或者與該模型的部分相關聯的數據庫設計。這種顯式共享的內容具備特殊的地位,在未與其餘團隊協商的狀況下不該改變。
定義一個持續集成過程,以保持內核模型的緊湊性,並與團隊的通用語言保持一致。常常其整合功能系統,雖然比團隊中持續集成的次數要少一些。
當兩個團隊處於上下游關係時,上游團隊可能獨立於下游團隊的命運而取得成功,下游的需求將以各類各樣的方式獲得解決,並帶來普遍的負面後果。
下游的團隊多是無助的,受上游優先級的擺佈。與此同時,上游團隊可能會收到抑制,擔憂會破壞下游系統。擁有複雜審批流程的繁瑣的變動請求過程並無改善下游團隊的問題。若是下游團隊對變動擁有否決權,上游團隊的自由發展就會中止。
所以:
在兩個團隊之間創建清晰的客戶/供應商關係,意味着將下游優先因素放到上游的規劃中。爲下游需求進行談判和預算任務,以便每一個人都瞭解承諾和時間表。
敏捷團隊能夠在規劃會議中讓下游團隊扮演上游團隊的客戶角色。聯合開發的自動化驗收測試能夠驗證來自上游的預期接口。將這些測試添加到上游團隊的測試套件中,做爲其持續集成的一部分,將使上游團隊自由地進行更改,而沒必要擔憂下游的反作用。
當兩個開發團隊有一個上下游關係時,上游沒有動力爲下游團隊的需求提供幫助,下游團隊就無能爲力了。利他主義可能會促使上游開發者作出承諾,但它們不太可能實現。相信這些好意會致使下游團隊基於沒法得到的特性來制定計劃。下游項目將被推遲,直到團隊最終學會接受上游所提供的東西。針對下游團隊的需求量身定製的接口是不太不可能的。
所以:
經過對上游團隊的模型進行嚴格的遵照,消除了限界上下文之間的轉換的複雜性。儘管這限制了下游設計人員的風格,而且可能不會產生應用程序的理想模型,可是選擇一致性極大地簡化了集成。此外,你將與上游團隊共享一種通用語言。上游在駕駛員的位置上,因此讓他們的交流變得容易是件好事。利他主義可能足以讓他們與你分享信息。
當與合做團隊銜接良好設計的限界上下文時,翻譯層能夠是簡單的,甚至是優雅的。可是,當控制或通訊不足以實現共享內核、合做夥伴或客戶供應商關係時,轉換就變得更加複雜。翻譯層採用了一種更具防護性的語氣。
一個提供給上游系統的大型接口最終可能徹底顛覆下游模型的意圖,從而使其被修改爲以一種特別的方式來模仿其餘系統的模型。遺留系統的模型一般是很薄弱的(若是不是大泥球的話),即便是明確設計的例外也可能不符合當前項目的需求,這使得遵循上游模型變得不切實際。然而,這種集成對於下游項目可能很是有價值甚至是必需的。
所以:
做爲下游客戶端,建立一個隔離層,根據您本身的領域模型,爲系統提供上游系統的功能。該層經過其現有的接口與另外一個系統進行通訊,只須要不多或不須要對其餘系統進行修改。在內部,這一層在兩個模型之間須要單向或雙向轉換。
一般對於每一個限界上下文,您將爲每一個部件定義一個翻譯層,您必須將其與上下文以外的組件集成在一塊兒。在集成是一次性的狀況下,爲每一個外部系統插入翻譯層的這種方法以最小的成本避免了模型的損壞。可是當你發現你的子系統有更高的要求時,你可能須要更靈活的方法。
當一個子系統必須與許多其餘的子系統集成時,爲每個子系統定製一個翻譯對象可能會使團隊陷入困境。有愈來愈多的維護,愈來愈多的擔憂何時會發生變化。
所以:
定義一個協議,將訪問您的子系統做爲一組服務。 打開協議,使全部須要與您集成的人均可以使用它。加強和擴展協議以處理新的集成需求,除非一個團隊有特殊的需求。而後,使用一次性翻譯對象來加強該特殊狀況的協議,以便共享協議可以保持簡單和一致。
這將使服務提供者處於上游位置。每一個客戶端都在下游,而且一般其中一些客戶端會遵照規定,有些客戶端會創建反腐層。具備開放主機服務的上下文可能與它的客戶端之外的上下文有任何關係。
兩個限界上下文模型之間的轉換須要一種通用語言。
直接轉換到現有的領域模型可能不是一個好的解決方案。這些模型可能過於複雜或被分解得很糟糕。也許他們說的是非法的。若是將其中一種用做數據交換語言,它實際上就會被凍結,不能響應新的開發需求。
所以:
使用一種文檔完整的公共語言,能夠將必要的領域信息做爲一種通用的通訊媒介來表達,並根據須要翻譯爲該語言。
許多行業以數據交換標準的形式創建了公共語言。項目團隊也開發本身的,在他們的組織內使用。
公共語言一般與開放主機服務相結合。
在定義需求方面,咱們必須冷酷無情。若是兩組功能之間沒有顯著的關係,它們能夠徹底相互分離。
整合老是代價很大的,有時候好處很小。
所以:
聲明一個限界上下文,使其與其餘上下文徹底沒有關聯,容許開發人員在這個小範圍內找到簡單的、專門的解決方案。
在咱們調查現有的軟件系統時,咱們試圖瞭解不一樣的模型在定義的邊界內是如何被應用的,咱們發現部分系統(一般是大型系統),模型是混合的,邊界是不一致的。
在沒有邊界的系統中,試圖描述模型的上下文邊界很容易陷入困境。
定義良好的上下文邊界做爲知識選擇和社會力量的結果出現(儘管建立系統的人在當時可能並不老是有意識地意識到這些緣由)。當這些因素缺失或消失時,將多個概念系統混合在一塊兒,使得定義和規則變得模棱兩可或相互矛盾。隨着特性的添加,系統是根據附加的邏輯來工做的。依賴關係縱橫交錯。因果關係變得愈來愈難以追蹤。最終,軟件會凝結成一個大的泥球。
在某些狀況下,大球泥其實是很是實用的(正如Foote和Yoder的原文所描述的那樣),但它幾乎徹底阻止了有用模型所須要的敏銳和精確性。
所以:
在整個混亂的周圍畫一個邊界,把它指定爲一個大泥球。不要嘗試在此上下文中應用複雜的建模。要警戒這種系統向其餘上下文蔓延的趨勢。
(見http://www.laputan.org/mud/mud.html。Brian Foote和Joseph Yoder)
做者:Zachary_Fan
出處:www.cnblogs.com/Zachary-Fan…
若是你想及時獲得我的自寫文章的消息推送,歡迎掃描下面的二維碼~。