[譯文]Domain Driven Design Reference(五)—— 為戰略設計的上下文映射

来源:https://www.cnblogs.com/Zachary-Fan/archive/2018/06/01/DDDReference5.html
-Advertisement-
Play Games

本書是Eric Evans對他自己寫的《領域驅動設計-軟體核心複雜性應對之道》的一本字典式的參考書,可用於快速查找《領域驅動設計》中的諸多概念及其簡明解釋。 其它本系列其它文章地址: [譯文]Domain Driven Design Reference(一)—— 前言 [譯文]Domain Driv ...


本書是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

 

 

如果你想及時得到個人自寫文章的消息推送,歡迎掃描下麵的二維碼~。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • CSS 聲明 給 CSS 屬性設置特定的值是 CSS 語言的核心功能。 CSS 引擎會通過計算,將對應的 CSS 聲明應用到頁面的每一個元素上,從而使得元素們以適當的方式佈局,並展示出適當的樣式。 特別需要記住的是: * CSS 的屬性和屬性值都是區分大小寫的。 * 屬性和屬性值之間,用英文半形冒號... ...
  • 微信客戶端在打開小程式之前,會把整個小程式的代碼包下載到本地。 緊接著通過 app.json 的 pages 欄位就可以知道你當前小程式的所有頁面路徑: { "pages":[ "pages/index/index", "pages/logs/logs" ] } 這個配置說明在 QuickStart ...
  • function isIE(){ var userAgent = navigator.userAgent, rMsie = /(msie\s|trident.*rv:)([\w.]+)/, rFirefox = /(firefox)\/([\w.]+)/, rOpera = /(opera).+ve... ...
  • 之前一段時間學習使用了gulp自動化構建工具,併在現在使用的項目上部署使用,同時在這做個筆記進行小結,以便加深記憶,如有理解錯誤的地方請不吝賜教 gulp 的解釋我就不多說了 這裡引用官網的一句話 Gulp.js 是一個自動化構建工具,開發者可以使用它在項目開發過程中自動執行常見任務,提高開發效率 ...
  • 第一次接觸 "qs" 這個庫,是在使用axios時,用於給post方法編碼,在使用過程中,接觸到了一些不同的用法,寫在這裡分享一下。 qs.parse 方法可以把一段格式化的字元串轉換為對象格式,比如 qs.stringify 基本用法 則和 相反,是把一個參數對象格式化為一個字元串。 排序 甚至可 ...
  • 出錯提示: angular2 Property 'map' does not exist on type 'Observable<Response>' 類型“Observable<Response>”上不存在屬性“map” 解決: 引入 rxjs/add/operator/map ...
  • 長期更新IT編程視頻教程,資料收集整理不易,需要一點費用 有意者加QQ:2773400,非誠勿擾! ...
  • 01.第一階段、Svn版本管理與代碼上線架構方案 02.第二階段、實戰Java高併發程式設計模式視頻 03.第三階段、深入JVM內核—原理、診斷與優化 04.第四階段、基於Netty的RPC架構實戰演練 05.第五階段、Git分散式版本控制系統權威指南 06.第六階段、Redis從入門到精通、集群與 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...