領域驅動設計(Domain-Driven Design DDD)——戰略設計1

一、概述

? ? ? ? 隨著系統的增長,它會越來越復雜,當我們無法通過分析對象來理解系統的時候,就需要掌握一些操縱和理解大模型的技術了。

? ? ? ? 最負雄心的企業欲實現一個涵蓋所有業務、緊密集成的系統。因大型公司的業務模型巨大且復雜,很難把它作為一個整體來理解且難以管理。按傳統做法,我們可以將其拆為較小的部分后組合。但問題在于,如何保證實現這種模塊化的同時,不失去集成所具備的好處;從而使系統的不同部分能夠進行互操作,以便協調各種業務操作。如果設計一個把所有概念都涵蓋進來的單一領域模型,它將會非常笨拙,而且將會出現大量難以察覺的重復和矛盾。而如果用臨時拼湊的接口把一組小的、各自不同的子系統集成到一起,又不具備解決企業級問題的能力,并且在每個集成點上都有可能出現不一致。通過采用系統的、不斷演變的設計策略,就可以避免這兩種極端問題。

? ? ? ? 即使這種規模的系統中采用領域驅動設計方法,也不要脫離實現去開發模型。每個決策都必須對系統開發產生直接的影響,否則它就是無關的決策。戰略設計原則必須指導設計決策,以便減少各個部分之間的互相依賴,在使設計意圖更為清晰的同時而不失去關鍵的互操作性和協同性。戰略設計原則必須把模型的重點放在捕獲系統的概念核心,也就是系統的“遠景”上。而且在完成這些目標的同時又不能為項目帶來麻煩。為了幫助實現這些目標,需探索三個主題:上下文、精煉和大型結構。

? ? ? ? 1、上下文是最不易引起注意的原則,但實際上它卻是最根本的。無論大小,成功的模型必須在邏輯上一致,不能有互相矛盾或重疊的定義。有時,企業系統會集成各種不同來源的子系統,或包含諸多完全不同的應用程序,以至于無法從同一個角度來看待領域。要把這些不同部分中隱含的模型統一起來可能是要求過高了。通過為每個模型顯式地定義一個Bounded Context,然后在必要的情況下定義它與其他上下文的關聯,建模人員就可以避免模型變得纏雜不清。

? ? ? ? 2、精煉可以減少混亂,并且把注意力集中到正確的地方。人們通常在領域的一些次要問題上花費太多的精力。整體領域模型需要突出系統中最有價值和最特殊的那些方面,而且在構造領域模型時應該盡可能把注意力集中在這些部分上。雖然一些支持組件也很關鍵,但絕不能把它們和領域核心一視同仁。把注意力集中到正確的地方不僅有助于把精力投入到關鍵部分上,而且還可以使系統不會偏離預期方向。戰略精煉可以使大的模型保持清晰。有了更清晰的視圖后,Core Domain的設計就會發揮更大的作用。

? ? ? ? 3、大型結構是用來描述整個系統的。在非常復雜的模型中,人們可能會“只見樹木,不見森林”。精煉確實有幫助,它使人們能夠把注意力集中到核心元素上,并把其他元素表示為支持作用,但如果不貫徹某個主旨來應用一些系統級的設計元素和模式的話,關系仍可能非常混亂。有幾種組織大型結構的方法,可以用它們作為基礎結構,去構建我們需要的大型結構。如Responsibility Layer(職責層) 、Evolving Order等。

? ? ? ? 這3種原則各有各的用處,但結合起來使用將發揮更大的力量。大型結構和精煉能夠幫助我們理解各個部分之間的復雜關系,同時保持整體視圖的清晰。Bounded Context(上下文)能夠使我們在不同的部分中進行工作,而不會破壞模型或是無意間導致模型的分裂。把這些概念加進團隊的Ubiquitous Language中,可以幫助開發人員找出大型模型的自己的解決方案。

二、保持模型的完整性

? ? ? ? 模型最基本的要求是它應該操持一致,術語總是具有相同的意義,并且不包含互相矛盾的規則:雖然我們很少明確地考慮這些要求。模型內部的一致性又叫統一(Unification),這種情況下,每個術語都不會有模棱兩可的意義,也不會有規則沖突。

? ? ? ? 但大型系統開發并非如此理想。在整個企業系統中保持這種水平的統一是一件得不償失的事情。在系統的各個不同部分中開發多個模型是很有必要的,但我們必須慎重地選擇系統的哪些部分可以分開,以及它們之間是什么關系。我們需要是一些方法來保持模型關鍵部分的高度統一。這需要通過有意識的設計決策和建立特定過程才能實現。大型系統領域模型的完全統一即不可行,也不劃算。

? ? ? ? 有時人們會反對這一點,多個模型看上去似乎不夠雅致。甚至對多個模型的抵觸會導致“極富雄心”的嘗試——將一個大型項目的所有軟件統一到單一模型中。如果想這樣做一定要考慮以下風險。

? ? ? ? (1)一次嘗試對遺留系統做過多的替換。
? ? ? ? (2)大項目可能會陷入困難,因為協調的開銷太大,超出了這些項目的能力范圍。
? ? ? ? (3)具有特殊需要的應用程序可能不得不使用無法充分滿足需要的模型,而只能將這些無法滿足的行為入到其他地方。
? ? ? ? (4)另一方面,試圖用一個模型來滿足所有人的需求可能會導致模型中包含過于復雜的選擇,因而很難使用。

? ? ? ? 此外,除了技術的因素外,權力上的劃分和管理級別的不同也可能要求把模型分開。而且不同模型的出現也可能是團隊組織和開發過程導致的結果。因此,即使完全的集成沒有來自技術方面的阻力,項目也可能面臨多個模型。

? ? ? ? 既然無維護一個涵蓋整個企業的統一模型,那就不要再受到這種思路的限制。通過預先決定什么應該統一,并實際認識到什么不能統一,我們就能夠創建一個清晰的、共同的視圖。確定了這些之后,就可以開始著手開始工作,以保證那些需要統一的部分保持一致,不需要統一的部分不會引起混亂或破壞模型。

? ? ? ? 我們需要用一種方式來標記出不同模型之間的邊界和關系。我們需要有意識地選擇一種策略,并一致地遵守它。

? ? ? ? 為識別、溝通和選擇模型邊界及關系,我們使用了一些模式,Bounded Context(限界上下文)定義了每個模型的應用范圍,而Context Map(上下文圖)則給出了項目上下文以及它們之間關系的總體視圖。這些降低模糊性的技術能夠使項目更好地進行,但還不夠。一旦確立了Context的邊界之后,仍需要持續集成這種過程,它能夠使模型保持統一。

? ? ? ? 其后,在這個穩定的基礎之上,我們就可以開始實施那些在界定和關聯Context方面更有效的策略——從通過共享內核(Shared Kernel)來緊密上下文,到那些各行其道(Separate Ways)地進行松散耦合的模型。

? ? ? ? 模型完整性模式的導航圖?

1、模式:Bounded Context

? ? ? ? 大型項目上會有多個模型共存,在很多情況下這沒什么問題。不同的模式應用于不同的上下文中。但也會有引起含糊和混亂的情況。如:兩個團隊為同一個新系統開發不同的功能,那么他們使用的是同一個模型嗎?他們的意圖是至少共享其所做的一部分工作,但卻沒有界限告訴他們共享什么、沒共享什么。而且他們也沒有一個過程來維護共享模型,或快速檢測模型是否有分歧。他們只是在系統行為不可預測時才意識到他們之間產生了分歧。

? ? ? ? 即使在同一個團隊中,也可能會出現多個模型。團隊的溝通可能會不暢,導致對模型的理解產生難以捉摸的沖突。原先的代碼往往反映的是早先的模型概念,而這些概念與當前模型有著微妙的差別。

? ? ? ? 每個人都知道兩個系統的數據格式是不同的,因此需要進行數據轉換,但這只是問題的表面。問題的根本在于兩個系統所使用的模型不同。當這種新差異不是來自外部系統,而是發生在同一個系統中時,它將更難發現。然而,所有大型團隊項目都會發生這咱情況。

? ? ? ? 任何大項目都會存在多個模型。而當基于不同模型的代碼被組合到一起后,軟件就會出現Bug、變得不可靠和難以理解。團隊成員之間的溝通變得混亂。人們往往弄不清楚一個模型不應該在哪個上下文中使用。

? ? ? ? 模型混亂的問題最終會在代碼不能正常運行時暴露出來,但問題的根源卻在于團隊的組織方式和成員的交流方法。因此,為了澄清模型的上下文,我們既要注意項目,也要注意它的最終產品(代碼、數據庫模式等)。

? ? ? ? 一個模型只在一個上下文中使用。這個上下文可以是代碼的一個特定部分,也可以是某個特定團隊的工作。如果模型是在一次頭腦風暴會議中得到的,那么這個模型的上下文可能僅限于那次討論。就拿本書來說,示例中所使用的模型的上下文就是那個示例所在的小節以及任何相關的后續討論。模型上下文是為了保證該模型中的術語具有特定意義而必須要應用的一組條件。

? ? ? ? 為了解決多個模型的問題,我們需要明確地定義模型的范圍——模型的范圍是軟件系統中一個有界的部分,這部分只應用一個模型,并盡可能保持統一。團隊組織必須一致遵守這個定義。

? ? ? ? 因此:

? ? ? ? 明確地定義模型所應用的上下文。根據團隊的組織、軟件系統的各個部分的用法以及物理表現(代碼和數據庫模式等)來設置模型的邊界。在這些邊界中嚴格保持模型的一致性,而不要受到邊界之外問題的干擾和混淆。

? ? ? ? Bounded Context明確地限定了模型的應用范圍,以便讓團隊成員對什么應該保持一致以及上下文之間如何關聯有一個明確和共同的理解。在Context中,要保證模型在邏輯上統一,而不用考慮它是不是適用于邊界之外的情況。在其他Context中,會使用其他模型,這些模型具有不同的術語、概念、規則和Ubiquitous Language的技術行話。通過劃定明確的邊界,可以使模型保持純粹,因而在它所適用的Context中更有效。同時,也避免了將注意力切換到其他Context時引起的混淆。跨邊界的集成必然需要進行一些轉換,但我們可以清楚地分析這些轉換。

? ? ? ? Bounded Context不是Module,有時這兩個概念易引起混淆,但它們是具有不同動機的不同模式。確實,當兩組對象組成兩個不同模型時,人們幾乎總是把它們放在不同的Module中。但人們也會在同一模型中用Module來組織元素,它們不一定要表達劃分Context的意圖。

識別Bounded Context中的不一致

? ? ? ? 很多征兆都可能表明模型中出現了差異。最明顯的是已編碼的接口不匹配。對于更微妙的情況,一些意外行為也可能是一種信號。采用了自動測試的Continuous Integration可以幫助捕捉到這類問題。但語言上的混亂往往是一種早期的警告信號。

? ? ? ? 將不同模型的元素組合到一起可能會引發兩類問題:重復的概念和假同源。重復的概念是指兩個模型元素(以及伴隨的實現)實際上表示同一個概念。每當這個概念的信息發生變化時,都必須更新兩個地方。每次由于新知識導致一個對象被修改時,必須重新分析和修改另一個對象。如果不進行實際的重新分析,結果就會出現同一概念的兩個版本,它們遵守不同的規則,甚至有不同的數據。更嚴重的是,團隊成員必須學習做同一件事情 的兩種方法,以及保持這兩種方法同步的各種方式。

? ? ? ? 假同源可能稍微少見一點,但它潛在的危害更大。它要是指使用相同術語(或已實現的對象)的兩個人認為他們是在談論同一件事情,但實際上并不是這樣。

? ? ? ? 當發現這些問題時,團隊必須要做出相應的決定。可能需要將模型重新整合為一體,并加強用來預防模型分裂的過程。分裂也有可能是由分組造成的,一些小組出于合理的原因,需要以一些不同的方式來開發模型,而且你可能也決定讓他們獨立開發。

三、參考文檔

DOMAIN-DRIVERN DESIGN
TACKLING COMPLEXITY IN THE HEART OF SOFTWARE

領域驅動設計
軟件核心復雜性應對之道

【美】Eric Evans 著 ? 趙俐 盛海艷 劉霞 等 譯

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716419.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716419.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716419.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2403d,d的108版本更改

原文 編譯器更改 1,在object.d中給TypeInfo_Class添加了.nameSig字段 2,總是在調用點求值像__FILE__此類關鍵字 3,現在可按整數數組轉換十六進制串 4,添加支持插值式序列 庫更改 1,isForwardRange,isBidirectionalRange和isRandomAccessRange現在帶可選元素類型 2,std.uni已…

K8s 鏡像緩存管理 kube-fledged 認知

寫在前面 博文內容為K8s 鏡像緩存管理 kube-fledged 認知內容涉及: kube-fledged 簡單介紹部署以及基本使用 理解不足小伙伴幫忙指正 不必太糾結于當下,也不必太憂慮未來,當你經歷過一些事情的時候,眼前的風景已經和從前不一樣了。…

springboot236基于springboot在線課程管理系統的設計與實現

基于SpringBoot在線課程管理系統的設計與實現 摘要 本文首先介紹了在線課程管理系統的現狀及開發背景,然后論述了系統的設計目標、系統需求、總體設計方案以及系統的詳細設計和實現,最后對在線課程管理系統進行了系統檢測并提出了還需要改進的問題。本系…

Spring Data Redis 使用方式

在Java中操作Redis 1. 在Java中操作Redis1.1 Redis的Java客戶端1.2 Spring Data Redis使用方式1.2.1 介紹1.2.1 環境搭建1.2.3 操作常見類型數據 1. 在Java中操作Redis 1.1 Redis的Java客戶端 Redis 的 Java 客戶端很多,常用的幾種: JedisLettuceSpri…

關于Axios接口請求超時處理與重試的方法教程

在前端開發中,使用Axios作為HTTP客戶端庫進行接口請求是非常常見的做法。然而,在實際開發中,我們經常會遇到網絡不穩定或服務器響應緩慢導致接口請求超時的情況。為了提高用戶體驗和程序的穩定性,我們需要實現接口請求超時的處理與…

UnityAPI的學習——Transform類

Transform類繼承自Component類,并實現了IEnumberable接口。Transform是GameObject必須擁有得一個組件,用來管理所在GameObject對象的坐標位置、選擇角度、和大小縮放。 Transform實現了IEnumberable接口,因此可以在程序中使用foreach()方法快…

echarts vue 動畫效果的水球圖、波浪圖教程

1、安裝插件 前提是已經安裝了echarts(我的版本是4.2.1) npm install echarts-liquidfill --save 我安裝了3.1.0版本的,結果運行時報錯"TypeError: wave.ensureState is not a function" 原因:echarts版本和echarts-l…

miniconda3徹底刪除虛擬環境

退出虛擬環境:確保您不在要刪除的虛擬環境中。如果在,使用命令 conda deactivate 來退出當前激活的虛擬環境。查看虛擬環境列表:運行命令 conda env list 或 conda info -e 來查看所有存在的虛擬環境及其路徑。刪除虛擬環境:使用命…

在VMware中安裝CentOS 7并配置Docker

VMware安裝CentOS 7 一、介紹 該文章介紹如何使用啟動U盤在虛擬機里面安裝系統,虛擬機版本為VMware Workstation 16 pro,Linux版本為CentOS Linux release 7.9.2009 (Core)。 二、安裝 1、創建虛擬機 點擊創建新的虛擬機 選擇典型就可以了&#xf…

前綴和算法題(區間次方和、小藍平衡和、大石頭的搬運工、最大數組和)

一、前綴和的原理和特點 prefix表示前綴和,前綴和由一個用戶輸入的數組生成。對于一個數組a[](下標從1開始),我們定義一個前綴和數組prefix[],滿足: prefix有一個重要的特性,可以用于快速生成p…

WordPress建站入門教程:如何安裝本地WordPress網站運行環境?

有些站長想要搭建WordPress網站,又擔心自己玩不轉,白白浪費購買域名和主機空間的費用。像這種情況,最好的做法就是在自己電腦上安裝一個WordPress網站運行環境,然后在本地電腦搭建WordPress,等熟悉掌握后再考慮購買域名…

設計模式學習筆記——抽象工廠模式

設計模式(創建型)—— 抽象工廠模式 在工廠模式中,我們為每一個類都設計了一個工廠,以此來獲取該類的對象,但缺點就是一旦類多了,工廠就多了,這時候我們可以考慮這些類間是否有關聯&#xff0c…

多輸入多輸出 | MATLAB實現GWO-Elman灰狼優化循環神經網絡多輸入多輸出預測

多輸入多輸出 | MATLAB實現GWO-Elman灰狼優化循環神經網絡多輸入多輸出預測 目錄 多輸入多輸出 | MATLAB實現GWO-Elman灰狼優化循環神經網絡多輸入多輸出預測預測效果基本介紹程序設計往期精彩參考資料 預測效果 基本介紹 Matlab實現GWO-Elman灰狼優化循環神經網絡多輸入多輸出…

kernel bypass 是什么?

文章目錄 一、kernel bypass 是什么二、Kernel Bypass技術優缺點三、Kernel Bypass技術應用領域四、Kernel Bypass的實現方式 一、kernel bypass 是什么 Kernel Bypass是一種技術,旨在通過繞過操作系統核來提高網絡數據包處理的性能和降低延遲。它的主要優點是高性能…

[LeetBook]【學習日記】有序鏈表合并

21. 合并兩個有序鏈表 將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 示例 1: 輸入:l1 [1,2,4], l2 [1,3,4] 輸出:[1,1,2,3,4,4] 示例 2: 輸入:l1 [], l2 [] …

如何在電腦上中恢復已刪除的視頻

您可以在電腦中恢復已刪除的視頻,無需任何繁瑣的工作。您所需要做的就是閱讀本文,了解恢復已刪除視頻的最佳方法。 一次錯誤的點擊可能會奪走您以視頻形式存儲的寶貴記憶。嗯,有些視頻不適合刪除,您希望永遠保留它們。失去這些寶…

如何使用Docker搭建StackEdit編輯器并結合內網穿透實現遠程辦公

文章目錄 前言1. ubuntu安裝VNC2. 設置vnc開機啟動3. windows 安裝VNC viewer連接工具4. 內網穿透4.1 安裝cpolar【支持使用一鍵腳本命令安裝】4.2 創建隧道映射4.3 測試公網遠程訪問 5. 配置固定TCP地址5.1 保留一個固定的公網TCP端口地址5.2 配置固定公網TCP端口地址5.3 測試…

優選算法|【雙指針】|1089.復寫零

目錄 題目描述 題目解析 算法原理講解 代碼 題目描述 1089. 復寫零 給你一個長度固定的整數數組 arr ,請你將該數組中出現的每個零都復寫一遍,并將其余的元素向右平移。 注意:請不要在超過該數組長度的位置寫入元素。請對輸入的數組 就…

LeetCode受限條件下可到達節點的數目

題目描述 現有一棵由 n 個節點組成的無向樹,節點編號從 0 到 n - 1 ,共有 n - 1 條邊。 給你一個二維整數數組 edges ,長度為 n - 1 ,其中 edges[i] [ai, bi] 表示樹中節點 ai 和 bi 之間存在一條邊。另給你一個整數數組 restr…

OJ:移除鏈表元素

203. 移除鏈表元素 - 力扣(LeetCode) 思路:這個題可以直接在原鏈表上進行修改,但是修改鏈表的指向是有點麻煩的,所以我們給兩個指針,phead和ptail,這是新鏈表的兩個指針,再給一個指針pcur來遍歷…