DDD解決軟件系統腐化之道

前言

任何人類的設計都會腐化,軟件系統也不例外數據庫

腐化之謎編程

隨着系統的規模增加和複雜度膨脹,系統會慢慢腐化。架構

因而改一個很簡單的下單地址,就會牽動整個交易系統十幾處的改動。框架

如何解決這種腐化之謎呢?微服務

參考計算機系統架構:測試

一個複雜的計算機系統架構包括:軟件系統元素,元素之間的聯繫,元素自己有本身特有屬性。架構設計

因而咱們能夠在架構角度參考計算機系統架構的實現。設計

架構建模

爲達到上面提到的架構建模的目的,引入領域驅動。3d

領域驅動圍繞業務概念構建領域模型,經過分離技術的方式實現應對複雜業務,及系統難以演進問題的解決方案。日誌

DDD帶來的不一樣:

  1. 將原有以技術角度審視架構演進的視角,轉換到以業務視角切入架構。
  2. 業務複雜度來源於領域自己,深刻領域,正確識別出領域深層次概念及關係。
  3. 將領域知識進行結構性表達,同時與編程模型保持一致,便造成了DDD。

基於問題空間的DDD模式

基於解空間的DDD模式

界限上下文

由顯示邊界限定的特定內聚職責,領域模型便存在於上下文以內。

界限上下文識別過程:

領域分析

如何經過真實業務驅動需求演化出DDD模型呢?

能夠採用事件風暴進行領域分析。

流程:

  1. PM,運營,RD共聚一堂
  2. 數小時內理解複雜領域
  3. 標記簡單的UML
  4. 工做流程與DDD完美匹配
  5. 事件流演化

以電商系統爲例

事件風暴 事件:PM關心真實事件 如:用戶訂單已發佈,商品已發佈 說明:關注點在於什麼領域模型發生了什麼變化。

命令風暴 命令:經過什麼活動產生了事件 如:用戶提交了訂單,開放平臺同步商品 說明:命令幫助咱們明確系統對外提供的能力,同時明確業務上的輸入 命令來源:用戶UI界面的操做,外部系統調用觸發,定時任務觸發

尋找聚合 聚合:一組相關性領域模型的聚合,用來封裝業務不變性,確保關聯緊密的領域模型內聚在一塊兒 如:訂單和商品 聚合的目的在於業務內聚,強迫RD進行簡化領域模型的關聯,實現業務設計高內聚低耦合的目的

劃分界限上下文

  1. 業務模型的問題是否同一個,是則放在同一個界限上下文中
  2. 若是一個聚合同時解決了多個問題,則須要定義不一樣的上下文肯定解決特定問題

界限上下文以內能夠自由選擇架構模式,如MVC,CQRS,微服務,SOA等。

不是全部界限上下文都採用領域驅動方式,非核心子域可參考數據驅動下的面向過程編程。

提取出面向切面的聚合層,以工程技術因素爲主要考慮點。

DDD的核心價值在於指導劃分界限上下文。

DDD分層設計

領域模型建設思路:

  1. 業務與技術關注點分離,依賴倒置,內部不依賴於外部且外部可替換
  2. 接口適配器架構
  3. 防腐層建設,領域模型依賴穩定性

參考六邊形架構:

架構目標:

  • 獨立於框架
  • 與數據庫分離
  • 可測試性
  • 與外部結構分離
  • 與UI分離

架構原則:

  • 關注點分離,切割不一樣層
  • 依賴原則:外部依賴內部,依賴倒置
  • 架構設計圍繞用例

結合CQRS設計

CQRS:命令查詢職責分離

將更復雜的領域模型拆分爲讀取和寫入兩部分。 將消息傳遞,數據日誌同步,領域事件和事件溯源使用到特定上下文。

領域驅動實踐

目前咱們活動營銷系統中,存在大量迭代需求都是針對運營需求所設計,需求自己具備複雜性和持續迭代性,故均已轉換採用領域驅動設計方式實現。

對現有及可預期的玩法需求進行了邏輯抽象,提供了統一業務領域玩法模型,爲運營提供統一玩法配置管理平臺,進行玩法需求配置,通過領域系統內核進行集成,對用戶輸出統一玩法活動UI及流程。

在局部演進及擴展需求,採用元數據+大字段應對信息的不肯定性,流程引擎+規則引擎構造玩法,DSL提供動態建立玩法資源配置的能力。

梳理事件風暴,抽象命令風暴,尋找履行命令的業務名詞,對相似的名詞玩法進行共性提取,作合適的抽象,同時創建通用語言描述及定義。

採用DDD分層架構+六邊形架構+CQRS模型,使得系統具有面向領域驅動的演進能力。

最後

DDD不是銀彈

哪些產品適用於DDD:

  1. 是不是複雜問題,或者子域內具備複雜性
  2. 業務是否重要且有很高的預期
  3. 是否可讓運營和PM介入
  4. 遵循迭代式的開放方法

領域模型好壞的標準:

  1. 模型反映了對於問題的抽象,抽象沒有統一的標準
  2. 模型是迭代演進的,須要持續集成,改進
  3. 通用語言,領域模型和代碼目標意圖一致

相關文章
相關標籤/搜索