限界上下文目的:
不在於如何劃分邊界 而在於如何控制邊界
對於統一語言:
限界上下文是語言的邊界
對於領域模型:
限界上下文是模型的邊界
語言的邊界以及模型的邊界可以 界定問題域
對於系統架構:
限界上下文確定了應用邊界和技術邊界
限界上下文 分離了業務邊界
目的:約束不同上下文的領域模型
例如 電商中的產品:
1 採購上下文:關注產品的進價、最小起訂量與供貨週期
2 市場上下文:關心產品的品質、售價,以及用於促銷的精美圖片和銷售類型
3 倉儲上下文:關心產品放在倉庫的哪個位置,產品的重量與體積,是否易碎品以及訂購產品的數量
4 推薦上下文:關注的是產品的類別、銷量、收藏數、正面評價數、負面評價數
不應該將這一概念建模爲單個類,否則就可能導致不同限界上下文對應的領域模型爲了代碼重用,而共享這個共同的 Product 類,導致限界上下文之間產生代碼的耦合
產品(Product)實體的設計也違背了“單一職責原則(SRP)”,它包含了太多本應分離的職責,適用於不同的上下文,從而變成了一個臃腫的上帝類
(產品對標基礎服務組的人員)
解決方案:
將產品看做是參與業務場景的角色,
遵循接口隔離原則(ISP)對 Product 實體類進行抽象,抽象出多個角色接口
方案一:讓定義的 Product 類去實現這多個接口,體現了“大對象小角色”的設計思路。
引入一個產品上下文,然後在其內部定義 Product 類去實現這些接口。
缺點:致了產品上下文同時依賴其餘四個限界上下文,形成了架構層面上限界上下文之間不必要的耦合
爲了避免重複,我們引入了耦合,這種設計上的顧此失彼是不可取的。
方案二:讓每一個限界上下文擁有自己的領域模型,該領域模型僅僅滿足符合當前上下文需要的產品唯一表示
不同的限界上下文都存在相同的 Product 領域模型,但由於有了限界上下文作爲邊界,使得我們在理解領域模型時,是基於當前所在的上下文作爲概念語境的(雖然都是Product,但是在不同上下文中角色不同)
優點:
保證了限界上下文之間的鬆散耦合
維持限界上下文各自領域模型的一致性
工作邊界被限界上下文明確
如果有兩個限界上下文的工作,分配給兩個不同的團隊。分配工作時,卻沒有按照限界上下文的邊界去組建團隊,
即每個團隊會同時承擔兩個限界上下文的工作。試想,這會造成多少不必要的溝通成本浪費
能夠將團隊與限界上下文重合,就能夠降低溝通成本,打造高效的領域特性團隊,專注於屬於自己的限界上下文開發。
限界上下文封裝了應用邊界
劃分限界上下文:
1:業務邊界的確立
2:控制技術複雜度,兼顧技術實現
高併發
外賣系統的訂單業務在某個特定的時間段比如中午 11 點到 13 點會達到訂單量的高峯值
將訂單業務從整個系統中剝離出來,作爲一個單獨的限界上下文對其進行設計,就可以從物理架構上保證它的獨立性,在資源分配上做到高優先級地擴展,在針對領域進行設計時,儘可能地引入異步化與並行化,來提高服務的響應能力
功能重用
賬戶管理並非系統的核心領域,但與賬戶相關的業務邏輯卻相對複雜。從功能重用的角度考慮,我們應該將賬戶管理作爲一個單獨的限界上下文,以滿足不同核心領域對這一功能的重用,避免了重複開發和重複代碼。
實時性
電商系統中,商品自然是核心,而價格(Price)則是商品概念的一個重要屬性。倘若僅僅從業務的角度考慮,在進行領域建模時,價格僅僅是一個普通的領域值對象
倘若該電商系統的商品數量達到數十億種,每天獲取商品信息的調用量在峯值達到數億乃至數百億次時,價格就不再是業務問題,而變成了技術問題。對價格的每一次變更都需要及時同步,真實地反饋給電商客戶
專門針對價格領域提供特定的技術方案,例如,通過讀寫分離、引入 Redis 緩存、異步數據同步等設計方法。此時,價格領域將作爲一個獨立的限界上下文,形成自己與衆不同的架構方案,同時,爲價格限界上下文提供專門的資源,並在服務設計上保證無狀態,從而滿足快速擴容的架構約束。
第三方服務集成
背景:一個電商系統需要支持多種常見的支付渠道,如微信支付、支付寶、中國銀聯以及各大主要銀行的支付。電商系統需要與這些第三方支付系統進行集成。不同的支付系統公開的 API 並不相同,安全、加密以及支付流程對支付的要求也不相同。
目標:
1 爲支付服務的客戶端提供完全統一的支付接口,以保證調用上的便利性與一致性(從上游角度考慮)
2 能解除第三方支付服務與電商系統內部模塊之間的耦合,避免引起“供應商鎖定(Vender Lock)”,也能更好地應對第三方支付服務的變化。(從下游角度考慮)
方法:
將這種集成劃分爲一個單獨的限界上下文。
遺留系統
避免已有模型對新開發模塊的影響,我們應該將這些已有功能視爲具有技術債的遺留系統,並將該遺留系統整體視爲一個限界上下文。