領域驅動設計(DDD)戰(zhàn)術上一些實踐

個人能力有限,如有問題歡迎指導

程序設計談不上什么最好,無論是面向過程編程,還是面向對象編程,我們都是在追求完美的道路上

不設計和過度設計都會對我們產生一些影響,最合適自己的設計才是最好的設計

DDD(Domain-Driven Design)領域驅動設計

  • 領域驅動設計并不是什么銀彈,簡單的項目并不需要 DDD,引入后反而增加項目難度
  • DDD 更加適合解決復雜的業(yè)務問題,并不是說DDD設計模式有什么壓倒性的優(yōu)勢也不是說它就是完美無缺的只是說它更適合干這事

要不要DDD

  • 在業(yè)務剛開始的時候,我們的功能都相對于比較簡單,就通過CRUD大法就能滿足我們的業(yè)務需求,
    隨著產品的各種需求加入,業(yè)務邏輯變的越來越復雜,各個模塊相互依賴,修改一個功能時需要花大量的時候去理解當時為什么這些寫后,然后再編寫代碼,甚至開發(fā)者自己都不知道這樣寫會不會影響其他模塊,這里我想對測試人員說一句你們辛苦了!

  • 產生這些問題的原因就是在于系統(tǒng)架構不清晰,劃分出來的模塊內****聚度低、高耦合****項目到達這個地步的時候我們就可以考慮要不要引入 DDD 來解決一些問題

貧血模型 VS 充血模型

  • 貧血模型: 比如在用戶類中我們定義了User的實體,但是操作User的并不是用戶類,而是 UserService,這樣的設計就是貧血模型簡單來說就是(只包含數據,不包含業(yè)務邏輯的類)
    ,就好比我們大學老師說的你有一個車但是不能開只能其他人去開破壞了面向對象的特性,是一種典型的面向過程的編程風格。

  • 充血模型: 我們知道了貧血模型是(只包含數據,不包含業(yè)務邏輯的類),那我們把數據和對應的業(yè)務邏輯被封裝到同一個類中是不是就是充血模型,Bingo 回答正確,你現在不僅擁有了車還可以開這就是面向對象編程風格

面向過程 VS 面向對象

需求把東西全部放到柜子你里面

  • 面向過程: 我們把整個東西放到一個大柜子里面堆在一起。如果修改了那個部分,可以需要修改其他部分,如果放的東西太多還不知道是否會產生一些不可以預知的錯誤,有可能就會出現祖?zhèn)鱞ug!
  • 面向對象: 我們把整個東西分類到一個一個的放在小柜子里面然后再放入一個大柜子,如果要修改也是修改需要修改的那個柜子,不會影響其他柜子

實體

用于個性特征或區(qū)分不同對象,判斷是不是同一個實體主要依據身份標識(identity),唯一身份標識和可變性(mutability)特征將實體對象和值對象(Value Object)區(qū)分開來。

  • 總結下來就是,實體是一個唯一的東西,可以在一段時間內持續(xù)變化

值對象

值對象用于度量和描述事務,當我們只關心某個對象的屬性時,該對象就可以作為一個值對象

  • 比如在快遞單的上的地址,你的地址可以和其他人的地址相同我們只需要關注地址的屬性就可以,并不需要給地址一個唯一標識
  • 值對象具有不變性,如果要修改的話直接替換整個值對象就行

聚合

將實體和值對象在一致性邊界內組成聚合,不變性和一致性邊界即是聚合的設計依據

  • 不變性: 不變性表示的是一個業(yè)務規(guī)則,該規(guī)則應該總是保持一致
  • 一致性邊界:單個事務只修改一個聚合實例

領域服務

領域中的服務表示一個無狀態(tài)的操作,它用于實現特定于某個領域的任務。當某個操作不適合放在聚合、值對象、實體上時,最好的方式便是使用領域服務

  • 在我的理解中上面那一句話就是,需要調用多個模型進行處理的就放在領域服務
  • eg:
應用服務:獲取輸入,發(fā)送消息給領域層,監(jiān)聽確認消息
領域服務:協(xié)調賬戶模型和郵件進行交互,執(zhí)行相應的領域行為。
基礎服務:按照應用服務的指示發(fā)送郵件。
  • 不過在實際開發(fā)過程中,最好吧領域對象封裝在領域服務中,領域知識限制在領域服務當中

工廠

將創(chuàng)建復雜對象和聚合的職責分配給一個單獨的對象,該對象本身并不承擔領域模型中的職責,但是依然是領域設計的一部分。
工廠應該提供一個創(chuàng)建對象的接口,該接口封裝了所有創(chuàng)建對象的復雜操作過程,同時,它并不需要客戶去引用那個實際被創(chuàng)建的對象。對于聚合來說,我們應該一次性地創(chuàng)建整個聚合、并且確保它的不變條件得到滿足

資源庫

簡單理解就是一個持久化機制,在DDD設計中一般將聚合實例放在資源庫中

  • 比如用戶實體,和地址值對象可以組合成一個聚合實例

探討項目結構 golang

- cmd  項目啟動文件
- conf 配置文件
- internal
  - app 項目名稱 
    - domain
     - dto        定義入參,出參
     - aggregate  聚合
     - valobj     值對象
     - entity     實體
     - dependency 抽象接口由外部 repository 實現
     - service    領域服務
    - facade     接口防腐層 調用其他接口
    - server     適配器
     - repository 依賴倒置實現儲存服務
     - grpcAdapter grpc 適配器
     - httpAdapter http 適配器
- pkg 三方庫工具類

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容