Monday, March 8, 2021

[複雜軟件設計之道-領域驅動設計] - 領域驅動設計基礎

1.1 領域驅動設計的起源與發展

DDD 是一種複雜軟件如何快速應對各種變化的解決之道。

1.1.1 程序員為難之處

軟件開發初期,有時沒有足夠時間收集所有的需求,即使收集,也不是從軟件角度去描述的。

需求帶有個人知識偏見和邏輯漏洞。

有些人開玩笑的說,程序員其實不是在編寫代碼,而是在摸索業務領域知識。

1.1.2 技術負債與軟件質量

技術負債就像技術前進途中的累贅一樣,會像滾雪球那樣越滾越大,不斷拖延增加新功能的步伐,最終可能無法再為系統添加新功能。因此,技術負債的存在是導致軟件質量下降的重要原因。軟件質量下降以後,系統難以維護和修復,就會導致項目失敗或者必須重寫代碼。

一個都不修復系統反而能正常運行;修復Bug時牽一動百,修改一處卻引起其他地方的連鎖故障反應……這些都是軟件質量低下的外在表現。

那麼如何降低技術負債呢?這裡存在一個適度問題。首先,代碼越多,複雜性越高,技術負債肯定越高,那麼就需要惜墨如金。有時為了寫出正確可運行的簡潔代碼,可能要刪除數十倍的代碼,但也不是代碼越少越好。有的代碼只是考慮功能的實現,沒有考慮到功能的對接或擴展,那麼當需要對功能實現擴展時,就發現難以下手,甚至需要採取黑客破解的方式強行入侵修改,這些都是原來代碼過於簡單僵化的表現。

1.1.3 ER 數據建摸與面向對象建模

ER數據建模 (實體-關係模型)的優點

ER模型往往依賴於數據庫技術,甚至與後者非常緊密地耦合在一起,雖然帶來了效率的提升,但是高效率不代表高質量,而軟件高質量卻能帶來高效率。

實體-關係模型的缺點

遺失業務上下文

依賴資料庫技術

物件導向的優點

物件導向的缺點

學習曲線較高

不適用所有類型的問題

分析和設計落差很多 

1.1.4 DDD 的誕生和發展

DDD是有關語言的建模技術,需要對語言有一定敏感性,有一定文科背景再結合邏輯推理能力則非常適合。

DDD需要對語言進行主謂賓分類,然後捕捉其中的謂語動詞或行為,將這些發生的動作抽象為命令模型,將發生過的事實抽象為領域事件模型,用領域事件替代狀態分析,例如音樂播放器有三種狀態:停止、播放、暫停,這是從狀態名詞角度分析的,而從領域事件角度分析則有:已停止、已播放和已暫停。當然中文中也常說“已停止狀態”,將事件和狀態混合在一起,其實兩者可以互相替代,只是動詞和名詞的區別。 

領域驅動設計全貌

 複雜性問題

1.2 領域驅動設計的特點

1.2.1 發現和理解問題

1.2.2 領域即邊界

BC 包含 Ubiquitous Language

名稱是認識萬物的第一步,從“無名”跨越到“有名”,其中的重要一步就是劃分邊界。因此,“名稱”和“邊界”兩者是互為聯繫的,當確定事物的邊界後才能給它命名,也可從名稱本身大概判斷其邊界或作用範圍。 

編程語言中有一個術語稱為“作用域”,英文為scope(其實也是邊界的意思),它是指變量的作用邊界是多大,從哪裡開始、從哪裡結束,如果作用域是函數方法內,那麼就是從函數方法開始執行到其結束這段範圍內。 

語言界限

科學上下文 蕃茄 -> 水果

享飪上下文 蕃茄 -> 蔬菜

1.2.3 解決複雜性

1.2.4 新的數據結構設計方式

1.2.5 需要注重產品的程序員


1.3 領域驅動設計的難點

1.3.1 業務策略和業務規則

1.3.2 統一語言與有界上下文

1.3.3 領域摸型的提煉


1.4 領域驅動設計的應用場景

1.4.1 哪些應用不適合

太簡單的系統

傳統 CRUD 系統

演示系統或教學案例 

 尚未理解領域的系統

1.4.2 適合微服務架構









No comments:

Post a Comment

n8n index

 【n8n免費本地端部署】Windows版|程式安裝x指令大補帖  【一鍵安裝 n8n】圖文教學,獲得無限額度自動化工具&限時免費升級企業版功能