[領域驅動設計]-01-基本概念

来源:https://www.cnblogs.com/xy1997/archive/2022/07/04/16443786.html
-Advertisement-
Play Games

領域驅動設計 領域驅動設計是關於軟體開發時架構設計與建模的方法論,隨著微服務架構的普及,領域驅動設計也隨之被廣泛使用。在本文中,將對領域驅動設計中的重要概念進行介紹。 界限上下文 在領域驅動設計中,首先需要根據客觀對象的實際內容以及對業務的理解,劃分出不同的領域。因此,引出了一個重要的概念:界限上下 ...


領域驅動設計

領域驅動設計是關於軟體開發時架構設計與建模的方法論,隨著微服務架構的普及,領域驅動設計也隨之被廣泛使用。在本文中,將對領域驅動設計中的重要概念進行介紹。

界限上下文

在領域驅動設計中,首先需要根據客觀對象的實際內容以及對業務的理解,劃分出不同的領域。因此,引出了一個重要的概念:界限上下文。界限上下文(bounded context)指的是根據業務知識自然劃分出的業務邊界。比如,以書店為例,書店有兩種基礎的業務上下文,分別是倉儲與銷售。在不同的上下文中,書店這一客觀實體將被以不同方式理解,所有與特定上下文相關的行為與邏輯都應該在這個上下文中被解決。當涉及到多個上下文交互的時候,通常會使用各個上下文中的門戶對象進行交流(這一點有點類似於聚合中使用聚合根進行統一的管理與訪問)

實體、值對象與聚合

做一個淺顯的類比,界限上下文好比一個城市的邊界。劃分完邊界後,可能還會根據業務的具體需要劃分出更細粒度的組織————聚合,聚合就好比在城市之中的各個街道與社區。當然,城市系統可以正常運作實際上離不開其中的人與物,類似於這一層級的概念,在領域驅動設計中我們將之稱作實體、值對象。

實體

  • 實體,擁有唯一標識符,經歷狀態變更後仍保持一致性。其重要特征是延續性和可標識性。比如在學生管理系統中,學生可以被設計為一個實體,每一個學生實體擁有唯一標識符。在不同的界限上下文中,名字相同的實體將會有不同的含義與側重點, 比如在倉儲的上下文中,我們關心書的尺寸、重量與類型,而在銷售的上下文中,我們關心書的內容、外觀、價格與評價。
  • 相比於貧血模型的優勢。所謂貧血模型指的是,模型僅對資料庫中的表結構進行了簡單映射,其餘的邏輯大量充斥在其他的類中,需要依賴大量的Utils類去計算與之相關的業務邏輯。

貧血模型的缺點[1]

  • 無法保護模型對象的完整性和一致性:對象的所有屬性都是公開的,只能由調用方來維護模型的一致性,缺乏保障。
  • 對象操作的可發現性極差:從對象的屬性上難以直觀的看出業務邏輯。什麼時候可以被調用?賦值的邊界是什麼?舉個例子,Long類型的值是否可以是0或者負數?
  • 代碼邏輯重覆:如校驗邏輯、計算邏輯等,很容易出現在多個服務的代碼塊里,這會提升後期維護的成本和bug出現的概率。
  • 代碼的健壯性差:比如一個數據模型的變化可能導致從上到下的所有代碼的變更。

值對象

  • 值對象,擁有一系列屬性,沒有唯一標識符。比如在學生管理系統中,家庭住址這一概念,可以由省、市、街道唯一編碼,是一組靜態的屬性值。

聚合與聚合根

  • 聚合,可以認為聚合是擁有一系列相關的,在特定界限上下文中的實體與值對象的集合。在聚合中,我們通常使用聚合根來管理和訪問聚合以及其中的其他成員。聚合根本質上也是一種實體,一般被稱作為根實體。對於一個特定的界限上下文,可以由單個或多個聚合構成。

Domain Primitive

Domain Primitive 是一個在特定領域里,擁有精准定義的、可自我驗證的、擁有行為的 Value Object。(註:Domain Primitive的概念和命名來自於Dan Bergh Johnsson & Daniel Deogun的書 Secure by Design)
通常使用DP時,會遇到以下幾種需求:

  • 讓隱性的概念顯性化
  • 讓隱性的上下文顯性化
  • 封裝多對象行為

常見的需要用到DP的場景:

  1. 有格式限制的String或Integer欄位,如電話號碼、地址、姓名、成績等,因為一般含有校驗邏輯,此時可以在DP中封裝校驗邏輯
  2. 複雜的數據結構的操作,如Map<String, List<Integer>>,可以使用DP來隱藏具體的細節。
    具體細節可以參考這一篇博文

領域之間的交互

不同領域之間通過相互交互,完成特定的系統功能。一個上游領域在一個特定業務流程中,可能會與多個下游領域交互。比如購物車服務在後續需要與訂單服務、倉儲服務、郵件服務進行交互。但由於各個服務是以微服務形式存在的,如果使用上游服務去聲明式(同步)地與下游服務進行交互,那麼一旦當中某一個下游服務因故障無法正確執行,則會造成整個系統狀態的不一致性。因此,使用非同步的交互方式(發佈-訂閱)能避免這一問題,上游服務可以在消息中間件中下發特定的消息,讓下游的服務非同步進行消費。同時,這種非同步的方式使上下游的服務相互解耦,當我們添加新的服務時,不需要改動無關的代碼。

事件風暴

開發人員與業務人員一起分析領域,並提出相關的建模。在每次討論中,只需要對特定的一個部分進行建模,而無需考慮全局的詳盡細節。可以以類似於敏捷開發的形式,迭代迴圈。通常需要確定的是業務相關的事件,以及事件相關的活動。通常來說,我們可以先定義完整個事件流,然後每個事件流後補充對應的活動與規則。

參考

[1]Repository模式
[2]DDD領域驅動設計-概述


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

-Advertisement-
Play Games
更多相關文章
  • 很多開發者在接入華為帳號服務時,經常會出現907135701的報錯。根據官網文檔說明,錯誤碼907135701表示: 這個錯誤碼在安卓和鴻蒙上都會出現,導致該報錯的原因有很多,開發者可以按照下麵幾點進行排查。 Android工程 原因一:開發者未在開發者聯盟上註冊應用產品信息,並生成應用對應的APP ...
  • 本文簡介 點贊 + 關註 + 收藏 = 學會了 在 JS 中,偽數組 是非常常見的,它也叫 類數組。偽數組可能會給 JS 初學者帶來一點困擾。 本文將詳細講解 什麼是偽數組,以及分別在 ES5 和 ES6 中將偽數組轉換成真正的數組 。 什麼是偽數組? 偽數組的主要特征:它是一個對象,並且該對象有 ...
  • 🎈前言 點贊 + 收藏 = 學會了 🐱‍💻線上展示 🐱‍👓代碼倉庫 先看看最終效果 這個效果非常簡單,只要看完實現原理應該就是有思路了。 🎗️原理 規定好容器尺寸 設置漸變背景: background: linear-gradient(...) 自己設置角度和顏色吧 設置背景尺寸比容器大 ...
  • Vue腳手架 eslintrc.js 配置速查 module.exports = { rules: { "no-alert": 0, //禁止使用alert confirm prompt "no-array-constructor": 2, //禁止使用數組構造器 "no-bitwise": 0, ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 原型和原型鏈 1. 原型 每個JS對象一定對應一個原型對象,並從原型對象繼承屬性和方法 1.1 __proto__ 對象的__proto__屬性值就是對象的原型對象 此屬性是過時的語法,現在建議使用Object.getPrototypeo ...
  • React中render()的目的是什麼? 每個React組件都必須有一個render(),它返回一個React元素,它是原生DOM組件的表示方式。 如果需要渲染多個HTML元素,則必須將它們組合在一個封閉標簽中,例如<form>、<group>、<div>等。次函數必須保持純潔,即每次調用時必須返 ...
  • 持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第23天,點擊查看活動詳情 本文簡介 點贊 + 關註 + 收藏 = 學會了 在我年輕時做過的開發中,毛玻璃應用得最廣是在複雜的背景圖上。 如果你希望在一個複雜的背景上添加文字,文字能清晰展示,並儘可能的保留原背景的話,使用毛玻璃的效 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 var length = 10; function fn () { return this.length + 1; } var obj = { length: 5, test1: function () { return fn(); } ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...