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