DDD學習與感悟——總是覺得自己在CRUD怎麼辦?

来源:https://www.cnblogs.com/Jcloud/archive/2023/12/04/17874259.html
-Advertisement-
Play Games

我們有時候也會看到一些博客看到或者聽到一些同事在說:這個業務有什麼難的,不就是CRUD麽?在軟體生命周期初期,我們通過CRUD這種方式我們可以快速的實現業務規則,交付項目,但隨著業務逐漸複雜,通過CRUD這種粗暴方式不可避免地會淹沒業務核心規則,產生很多祖傳(屎山)代碼,系統交接的時候我們經常會聽到... ...


一、DDD是什麼?

DDD全名叫做Domins drives Design;領域驅動設計。再說的通俗一點就是:通過領域建模的方式來實現軟體設計。

問題來了:什麼是軟體設計?為什麼要進行軟體設計?

軟體開發最主要的目的就是:解決一個問題(業務)而產生的一個交付物(系統)。而軟體設計旨在高效的實現複雜項目軟體。也就是說軟體設計是從業務到系統之間的橋梁。

而DDD則是在複雜業務場景下一種更高效更合理的軟體設計思維方式和方法論。

二、以前的軟體設計思維是什麼?

絕大部分從事軟體開發的人,不管是在學校還是剛開始工作,都是從ER圖開始。即直接通過業務設計資料庫模型和數據關聯關係。這種思維根深蒂固的印在了這些人的頭腦里(包括我自己)。因此在軟體設計過程中習慣性的直接將業務轉化為數據模型,面向數據開發。也就是我們所說的CRUD。我們有時候也會看到一些博客看到或者聽到一些同事在說:這個業務有什麼難的,不就是CRUD麽?

不可否認的是,在軟體生命周期初期,通過CRUD這種方式我們可以快速的實現業務規則,交付項目。然而一個系統的生命周期是很長的並且維護階段的生命周期占絕大部分比例。 隨著業務的發展,業務規則越來越複雜,通過CRUD這種粗暴方式,讓工程代碼越來越複雜,通常一個方法可能會出現幾百甚至上千行代碼,各種膠水代碼和業務邏輯混合在一起,導致很難理解。

這種系統交接給另一個同學或者新進來的同學後,可能需要花費很長的時間才能理解這個方法,原因就是因為這種膠水代碼淹沒了業務核心規則。所以在現實場景中,我們經常會聽到,上一個開發是SB,或者自嘲自己是在屎山上面繼續堆屎。

三、DDD思想下的軟體設計

DDD的思想是基於領域模型來實現軟體設計。那麼,什麼是領域模型?領域模型怎麼得來呢?

DDD思想,將軟體的複雜程度提前到了設計階段。基於DDD思想,我們的設計方式完全變了。

統一語言

首先,將業務方、領域專家以及相關的產研人員都聚攏在一起,共同探討出業務場景和要解決的問題,統一語言。來確保所有人對於業務的理解都是一致的。

這裡的統一語言不是指某種具體的技術語言,而是一種業務規則語言。所有人必須要能夠理解這種統一語言。

戰略設計

其次,我們根據待解決的問題空間,進行戰略設計。所謂的戰略設計就是根據問題空間在巨集觀層面識別出限界上下文。比如說一個電商業務,我們需要交付一個電商系統,根據電商業務的特點,需要劃分出用戶、商品、訂單、倉儲等限界上下文,每一個限界上下文都是一個獨立的業務單元,具有完整的業務規則。

識別領域模型

然後,再分別針對上下文內的業務領域進行建模,得到領域模型。在DDD思想中,領域模型中通常包含實體、值對象、事件、領域服務等概念。我們可以通過“事件風暴”的方式來識別出這些概念。

註意,“事件風暴”和“頭腦風暴”是有區別的。“頭腦風暴”的主要目的是通過發散思維進行創新,而“事件風暴”是DDD中的概念,其主要目的是所有人一起根據統一語言和業務規則識別出事件。再根據事件識別出實體、值對象、領域服務、指令、業務流等領域模型中的概念。

所謂事件指的是已經發生了的事情。比如用戶下了一個訂單、用戶取消了訂單、用戶支付了訂單等

根據事件,我們可以識別出實體,比如上面這個例子中的訂單實體,以及指令:取消、支付、下單等。

程式設計

識別出領域模型之後,我們就可以根據領域模型來指導我們進行程式設計了。這裡的程式設計包括業務架構、數據架構、核心業務流程、系統架構、部署架構等。需要註意的是,在進行程式設計時,我們依然要遵循DDD中的設計規範。否則很容易走偏方向。

編寫代碼

有了完整的程式設計之後,我們就可以進行實際的工程搭建以及代碼編寫了。

這個階段需要註意的是,我們需要遵循DDD思想中的架構設計和代碼設計。實際上這個階段也是非常困難的。因為基於DDD思想下的工程架構和我們傳統的工程架構不一樣。

基於DDD思想下,編碼過程中我們經常會遇到的一個問題是:這個代碼應該放在哪裡合適。

工程結構

在DDD中,標準的工程結構分為4層。用戶介面層、應用層、領域層和基礎設施層。

DDD中,構建軟體結構思維有六邊形架構、CQRS架構等,它們是一種思想,是從邏輯層面對工程結構進行劃分,而我們熟知的SOA架構以及微服務架構是從物理邏輯層面對工程結構進行劃分,它們有著本質的區別,但是目標都是一樣的:構建可維護、可擴展、可測試的軟體系統。

代碼編寫

在DDD中,最為複雜的便是領域層,所有的業務邏輯和規則都在這裡實現。因此我們經常會遇到一個問題就是代碼應該放在哪裡。

在具體落地過程中會遇到這些問題,解決這些問題沒有銀彈,因為不同的業務有不同的處理方式,這個時候我們需要與領域專家們討論,得出大家都滿意的處理方案。

代碼重構

沒有不變的業務。因此我們需要結合業務的發展而不斷迭代更新我們的領域模型,通過重構的方式來挖掘隱形概念,再根據這些隱形概念去不斷的調整我們的戰略設計以及領域模型。使得整個軟體系統的發展也是螺旋式迭代更新的過程。

通過以上的介紹,我們實現DDD的過程如下:

四、總結

通過對於DDD的理解,其實不難發現,程式員的工作重心變了,程式員其實不是在編寫代碼,而是在不斷的摸索業務領域知識,尤其是複雜業務。

所以如果總是覺得自己在CRUD,有可能不是你做的業務沒價值,而是自己對於業務的理解還不夠深;如果總是沉迷於代碼編寫,可能你的發展空間就會受限了。

作者:京東科技 孫黎明

來源:京東雲開發者社區 轉載請註明來源


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文分享自華為雲社區《深入理解HarmonyOS UIAbility:生命周期、WindowStage與啟動模式探析》,作者:檸檬味擁抱。 UIAbility組件概述 UIAbility組件是HarmonyOS中一種包含UI界面的應用組件,主要用於與用戶進行交互。每個UIAbility組件實例對應最 ...
  • 只有不斷學習和成長,才能適應這個快速變化的世界。 1. 懶載入 1.1 React 懶載入 React 中懶載入 Lazy 與 Suspense 需要搭配使用。 React.lazy 定義: React.1azy 函數能讓你像渲染常規組件一樣處理動態引入的組件。其實就是懶載入。 為什麼代碼要分割? ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 測試發現了一個問題,簡單描述問題就是通過函數刪除一個數組中多個元素,傳入的參數是一個數組索引。 然後發現實際效果有時刪除的不是想要的內容。 具體 Bug 代碼實現: const arr = [1,2,3,4,5,6,7]; cons ...
  • 本文先介紹了 wasm-pack 官方的教程,還有其他組件測試、發佈等的流程先不在這裡介紹了。以下用一個實際開發中的模塊來說一下開發 wasm 組件過程中遇到的問題和解決方法。 ...
  • 小程式上想要實現成點擊標簽跳轉某標簽,在標簽內滾動時隨著超過滾動內容 tab 選中態變化。 藉助了 @vant/weapp 框架 index.wxml <view class="list-page"> <van-tabs sticky active="{{ active }}" bind:click ...
  • 註意:在模擬器用滑鼠滾動是不會切換游標的,因為使用的是觸摸滑動。【自定義類型貼在最後了】 script 部分如下: import { onMounted } from 'vue' import type { orderDetail } from '@/types/category' import t ...
  • 最近有個需求需要實現自定義首頁佈局,需要將屏幕按照 6 列 4 行進行等分成多個格子,然後將組件可拖拽對應格子進行渲染展示。 示例 對比一些已有的插件,發現想要實現產品的交互效果,沒有現成可用的。本身功能並不是太過複雜,於是決定自己基於 vue 手擼一個簡易的 Grid 拖拽佈局。 完整源碼在此,在 ...
  • 2.7Python(目前ArcGIS使用)代碼轉化為3.5Python(目前ArcGIS Pro使用)代碼 Analyze Tools For Pro (2to3命令) 基本操作 調用ArcToolbox的兩種形式 #arcpy.ToolboxAlias.ToolName() #arcpy.Tool ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...