快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队
1 前言
本文与大家一起学习并介绍领域驱动设计(Domain Drive Design) 简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计,本篇并不会从深层大论述讲解落地实现,这些大家可以在了解入门后再去深层次学习探讨或在后续进阶和高级篇了解,希望通过本文介绍,可以让大家快速了解DDD并有一个基础的认知,DDD本身就是理论的集合,很难在不积累理论情况下来有效的实施DDD,仅仅看一些代码案例后就开搞,最终出来东西也是东施效颦,莫要好高骛远。 最后期望大家在工作中能多思考,如你所负责项目如果用DDD如何设计、以及会面临哪些挑战。
学习了解DDD之前,期望大家可在温顾下以往我们所了解掌握一些知识,努力让自己所学所掌握的内容沉淀下来,推荐阅读系列。
- Head First 设计模式:基础面向对象概念和重要的设计模式;
- UML面向对象建模基础:从需求到分析,从分析到设计,从设计到编码,UML都有用武之地
- 实现领域驱动设计:很厚,更加务实,推荐阅读
- 领域驱动设计:张逸-DDD开山之作,挺玄幻的,多读几遍受益匪浅;
2 定义与概念
领域驱动设计(DDD)提出是从系统的分析到软件建模的一套方法论。将业务概念和业务规则转换成软件系统中的概念和规则,从而降低或隐藏业务复杂性,使系统具有更好的扩展性,以应对复杂多变的现实业务问题。总结它是一套完整而系统的设计方法、是一种设计思维、一种方法论,并不是"系统架构",一种架构设计原则、思维。
2.1、为什么要使用"领域驱动设计",或者说其用途,应用场景式什么?
-
善于处理高复杂业务的产品研发、可帮助我们提炼稳定的产品内核(领域模型中称为核心域);
-
通过建模可提高建模高内聚、降低模型间的耦合度,提高系统的可扩展性与稳定性;
-
强调团队与领域专家的合作沟通,有助于建立一个沟通良好的团队组织;
-
统一设计思想与设计规范,有助于提高团队成员的架构设计能力和面向对象设计能力;
-
现有的微服务建构都是遵循领域驱动设计的架构原则;
-
如果你负责的软件系统并不复杂,那么,你确实不需要学习领域驱动设计!
2.2、领域驱动设计跟时下流行的架构思维最大的区别是什么?
领域驱动设计的思维是:对象+行为+服务,所有的设计围围绕着对象、行为、服务展开;
时下流行架构设计思维是:基于MVC分层架构进行纵向扩展,分业务模块进行产品横向扩展;
2.2.1. 传统的方案
三层应用架构:数据-应用(业务逻辑层)-展现,通常是以数据位为起点进行数据库分析设计。
-
服务层过重,数据模型失血,没东西;
-
面条式编程或者面向数据库编程,服务层围绕数据库作业完成业务逻辑,经常一条线撸到底;
3) 代码一整块一整块的过重,很难扩展复用;
- 数据库模型只是数据库映射,没有相关的行为支撑,行为都被上一层Service给完成等了,因此是失血 的领域模型;
2.2.2. 领域驱动方案
架构四层在DDD分层结构中将三层中业务逻辑拆解为应用层和领域层,核心业务逻辑表现下沉到领域层去实现,以业务领域模型为核心建模(面向对象建模),更能体现对现实世界的抽象,其优点如下
1) 轻服务层+充血的领域模型;
-
领域模型封装和实现各自应有的行为,可以认为是一个高内聚、低耦合的组件;
-
由于模型集数据与行为于一身,是一种自解释的对象,代码复用性高,业务逻辑清晰明确;
- 用户界面层:主要职责是通过用户界面向用户显示数据信息,同时解释用户的命令,并把用户的请求发送到应用层。
- 应用层:通过调用基础设置和领域层完成数据资源操作及业务流程编排,相当于BS层;
- 领域层:将业务逻辑高度内聚到领域层,所以领域层是整个系统的核心,它只与实际业务相关,不关心任何技术细节,尽可能做到与持久化无关;
- 基础设施层:包含了任何类型的框架、数据库访问代码或者公共的方法等,纯技术的一层;
2.3、如何学习领域驱动设计
没有谁能够做到领域驱动设计的一蹴而就,所谓"理论联系实际",在刚开始接触或学习设计领域驱动时,总会有一种诉求希望能给出公式般的设计准则或规范,似乎软件设计就像拼积木一般,只要遵循图示给出的拼搭过程,不经思考就能拼出期待的模型,这似乎不切实际的幻想,要掌握领域驱动设计,首先要了解掌握一些概念以知识理论,在此基础之上思考这些概念背后蕴含的原理,设计原则,思考限界上下文(Bounded Context)边界的划分,实际还是围绕"高内聚、低耦合"原则的体现,只是我们考虑什么内容才是高内聚,如何抽象才能做到低耦合,在分层架构中,各层之间该如何协作?出现了依赖如何解耦,仍然需要从重用与变化的角度去思考设计决策。
3 领域驱动设计
领域驱动设计强调以"领域"为核心驱动力,通过模型驱动设计来保障领域模型与程序设计的一致,领域模型不应该包含任何技术实现因素,模型中的对象真实的表达了领域概念,却不受技术实现的约束,领域模型本身和技术无关,领域驱动从设计上划分为战略设计和战术设计。
- 一个领域是由一个或多个模型组成;
- 从定义上讲模型是领域的抽象;
- 从理解上将模型可以认为是一个高内聚、低耦合的组件、模块,也可以称为一个子领域;
- 模型重在建模过程,建模过程会抽象出一系列领域对象和领域服务;
- 在DDD中,定义一系列的标准"领域元素"用于领域建模;如战术设计元模型
3.1. 战略设计
强调业务战略上的重点,如何按重要性分配工作,以及如何进行最佳,遵循量大原则:
-
必须指导设计决策,以便减少各个部分之间的相互依赖,在使用设计意图更为清晰的同时而又不失去关键的互操作性和系统性;
-
必须把模型的重点放在捕获系统概念核心,也就是系统的"远景"上。
3.1.1 子域划分
整个业务领域的一部分,关注与宏观业务,通过对大领域进行划小在业务间划分出概念上分界线,便于在系统筹划阶段决策如何分配资源(人、钱)。
1) 核心子域:领域中最有价值和最核心的部分,产品成败的关键,核心竞争力,在DDD开发中,主要关注核 心域,给予最高优先级;
-
支撑子域:项目中对核心子域起着支撑作用的相关功能,专注于业务的某个反面;
-
通用子域:与项目意图无关的内聚子领域,解决一些通用问题,任何专有的业务都不应该放在通用子域;
3.1.2. 战略建模
关注点在于系统物理划分,根据你对领域的分割结果及公司或部门的组织结构决策如何划分子系统,比如分出几个,系统间如何交互,该层面往往暂不会涉及够多技术细节。
1) 限界上下文(Bounded Context):通俗讲指系统中模块,微服务架构中的子服务、单体中"包(Java)"或名称空间(C#),对系统的一个物理划分,限定了领域模型的边界,在更深层次介绍深挖,这东西得分成两个词:限界、上下文,可以理解成系统设计之初,你需要画一个圈设置一个范围,保证领域模型限制在这个圈内不可串场,这个‘圈’即为限界上下文。
-
通用语言:用于统一领域专家、产品、研发、测试大家在使用的语言,避免出现需求理解不一致,设计与需求不一致,沟通不顺畅等问题,简单来说大家在一起聊某个东西的时候都能明白彼此所致的是什么,场景不同,同一个词就会有着不同含义。
-
上下文映射图:用图的方式,表达出限界上下文之间关联,后续会单独在详细介绍上下文映射图,如 合作关系、防腐层、大泥球等;
3.2. 战术设计
依赖于领域模型和通用预言,通过技术模式将领域模型和通用预言中的概念映射到代码实现中。随着模型的进化,代码实现也会进行重构,以更好的体现模型概念。
- 主要包括:
-
代表领域中的概念,如实体、值对象、领域服务、模块等;
-
用于管理对象的生命周期。如聚合、工厂、仓库等;
-
用于集成或跟踪,如领域事件等;
3.3. 名词解释
-
领域/子域:什么领域?从广义上将,领域即是一个组织所做的事情以及所包含的一切,领域可大可小有界限,不是无限大,如电商领域,交易领域,购物领域等,比如我们常听客户说“我们有这样几块业务”一般来说这里所谓"几块儿"就是指子域 。
-
实体(entity):这个词被我们广泛使用,甚至过分使用,实体是一个重要的概念,一个典型实体应具备3个要素(身份标识、属性、领域行为),必须有唯一的身份标识,没有身份标识的领域对象就不是实体。如:User对象就是一个实体。
-
属性:实体的属性用来说明主体的静态特征,并持有数据与状态。
@Data
public class Product{private String sku;private String name;private Price price;
}
- 领域行为:实体拥有领域行为,可以更好地说明其作为主体的动态特征。一个不具备动态特征的对象不属于领域行为。
@Data
public class Product{private String sku;private String name;private Price price;//变更状态的领域行为public void changePriceTo(Price newPrice){//设计产品新加个.......}
}
- 值对象(value object):比较抽象,通常作为实体的属性,区分值对象与实体的区别在于,值对象是不可变的,并且没有唯一标识,仅由其属性的值定义,参与则对它的判断是依据值还是依据身份标识,前者是值对象,后者是实体;
举个小例子:订单项和订单的关系:多对一,一个订单里有多条订单项,一个订单项,只会出现在一个订单里,组合关系,部分不能脱离主体单独存在
public class Order {int id;User user;
}public class OrderItem {private int id;private Product product;private int num;private Order order;
}
6) 聚合根:聚合中需要指定一个实体作为聚合根来作为整个聚合的对外触电,也就是说外部只能通过聚合根实现对内部对象的访问,这样的限制可以对内部对象实现最大化的保护。
4 价值是什么
几乎所有项目的发展都有这样一个规律:初期需求简单,中后期业务激增系统复杂度升级,导致最初的设计理念需要大刀阔斧的改革,所以,系统越复杂、代码规模越大,DDD 的优势就越明显。
- 合作沟通:强调团队与领域专家的合作沟通,有助于建立一个沟通良好的团队组织;
- 统一思想:统一设计思想与设计规范,有助于提高团队成员的架构设计能力和面向对象设计能力;
- 系统灵活:通过建模可提高模型的高内聚,降低模型建的耦合度,提高系统的可扩展性与稳定性;
- 产品内核:善于处理高复杂度业务产品研发,可帮助我们提炼稳定的产品内核;
- 业务沉淀:领域模型是系统的核心,是领域内业务的直接沉淀,具有非常大的业务价值。
5 基础篇结束语
微服务划分的一个重要理论基础就是领域驱动设计,但由于DDD门槛高、概念多,体系庞大又抽象,再加上实践经验和案例缺少,很多开发人员对DDD存在不少疑惑,或只停留在平时依靠检索或身边同事谈及耳闻了解DDD,通过本篇初步认识了领域驱动设计、前期我们先暂短介绍这里,后续会将从代码层面入手分享DDD实现落地。
作者:京东物流 边雷
来源:京东云开发者社区 自猿其说Tech 转载请注明来源
相关文章:
快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队
1 前言 本文与大家一起学习并介绍领域驱动设计(Domain Drive Design) 简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计,本篇并不会从深层大论述讲解落地实现,这…...
C++学习笔记(堆栈、指针、命名空间、编译步骤)
C 1、堆和栈2、指针2.1、指针的本质2.2、指针的意义2.3、清空指针2.4、C类中的this 3、malloc and new4、命名空间4.1、创建命名空间4.2、使用命名空间 5、编译程序的四个步骤5.1、预处理5.2、编译5.3、汇编5.4、链接 1、堆和栈 堆(heap)和栈࿰…...
Rust Yew应用开发的事件初探
在Rust的世界中有一个叫Yew的框架,它借鉴了React的思想。我的React代码也写了不少,今天就聊一下我个人对Yew应用开发中事件相关部分的体验。 我的也是才开始学习Rust和Yew,说得不对的地方还请大家多多指教。 下面的例子涉及到3个组件 Paren…...
高并发下单例线程安全
1.使用静态内置类实现单例模式 自定义线程池 2.使用static代码块实现单例 3.使用静态内置类实现单例模式 4.使用static代码块实现单例 public class MySingleton {//使用volatile关键字保其可见性volatile private static MySingleton instance null;private MySingleton…...
【EKF】EKF原理
原理简述 卡尔曼滤波可以在线性模型,误差为高斯模型的情况下,对目标状态得出很好的估计效果,但如果系统存在非线性的因素,其效果就没有那么好了。比较典型的非线性函数关系包括平方关系,对数关系,指数关系…...
蓝桥杯官网填空题(古堡算式)
题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE ∗ ?EDCBA 他对华生说:“ABCDE 应该代表不同的数字,问号…...
Python---集合set
集合特点 1. 可以容纳多个数据 2. 可以容纳不同类型的数据 3.数据是无序存储的(不支持下标索引) 4. 不允许重复数据存在 5. 可以修改 6. 支持for循环,不支持while循环 集合定义 # 定义集合 变量 {元素1, 元素2, 元素3, 元素4...}# 定…...
LORA项目源码解读
大模型fineturn技术中类似于核武器的LORA,简单而又高效。其理论基础为:在将通用大模型迁移到具体专业领域时,仅需要对其高维参数的低秩子空间进行更新。基于该朴素的逻辑,LORA降低大模型的fineturn门槛,模型训练时不需…...
Azure + React + ASP.NET Core 项目笔记一:项目环境搭建(一)
不重要的目录标题 前提条件第一步:新建文件夹第二步:使用VS/ VS code/cmd 打开该文件夹第三步:安装依赖第四步:试运行react第五步:整理项目结构 前提条件 安装dotnet core sdk 安装Node.js npm 第一步:新…...
html 学习 之 文本标签
下面是一些常见的HTML文本标签(,,,,和)以及它们的作用: 标签 (Emphasis - 强调): 作用:用于在文本中表示强调或重要性。 示例: <p>这是一段文本,&l…...
联发科3纳米芯片预计2024年量产,此前称仍未获批给华为供货
9月7日,联发科与台积电共同宣布,联发科首款采用台积电3纳米制程生产的天玑旗舰芯片开发进度顺利,已成功流片,预计将在2024年量产,并将于下半年正式上市。这款旗舰芯片并非今年上市的天玑9300。 据联发科总经理陈冠州介…...
搭建vue3项目并git管理
搭建vue3项目 采用vue3的create-vue脚手架搭建项目,底层是vite,要求环境 node 16.0及以上(node -v检查node版本) 在文件夹右键->终端-> npm init vuelatest,输入项目名称,根据需要选择是否装包 src…...
【Azure OpenAI】OpenAI Function Calling 101
概述 本文是结合 github:OpenAI Function Calling 101在 Azure OpenAI 上的实现: Github Function Calling 101 如何将函数调用与 Azure OpenAI 服务配合使用 - Azure OpenAI Service 使用像ChatGPT这样的llm的困难之一是它们不产生结构化的数据输出…...
立晶半导体Cubic Lattice Inc 专攻音频ADC,音频DAC,音频CODEC,音频CLASS D等CL7016
概述: CL7016是一款高保真USB Type-C兼容音频编解码芯片。可以录制和回放有24比特音乐和声音。内置回放通路信号动态压缩, 最大42db录音通路增益,PDM数字麦克风,和立体声无需电容耳机驱动放大器。 5V单电源供电。兼容USB 2.0全速工…...
【Flutter】支持多平台 多端保存图片到本地相册 (兼容 Web端 移动端 android 保存到本地)
免责声明: 我只测试了Web端 和 Android端 可行哈 import dart:io; import package:flutter/services.dart; import package:http/http.dart as http; import package:universal_html/html.dart as html; import package:oktoast/oktoast.dart; import package:image_gallery_sa…...
postgresql 安装教程
postgresql 安装教程 本文以window 15版本为教程 文章目录 postgresql 安装教程1.下载地址2.以管理员身份运行3.选择安装路径,点击Next4.选择组件(默认都勾选),点击Next5.选择数据存储路径,点击Next6.设置超级用户的…...
手写数据库连接池
数据库连接是个耗时操作.对数据库连接的高效管理影响应用程序的性能指标. 数据库连接池正是针对这个问题提出来的. 数据库连接池负责分配,管理和释放数据库连接.它允许应用程序重复使用一个现有的数据路连接,而不需要每次重新建立一个新的连接,利用数据库连接池将明显提升对数…...
在CentOS7上增加swap空间
在CentOS7上增加swap空间 在CentOS7上增加swap空间,可以按照以下步骤进行操作: 使用以下命令检查当前swap使用情况: swapon --show创建一个新的swap文件。你可以根据需要指定大小。例如,要创建一个2GB的swap文件,使用…...
@Autowired和@Resource
文章目录 简介Autowired注解什么是Autowired注解Autowired注解的使用方式Autowired注解的优势和不足 Qualifier总结: Resource注解什么是Resource注解Resource注解的使用方式Resource注解的优势和不足 Autowired vs ResourceAutowired和Resource的区别为什么推荐使用…...
QTableView通过setColumnWidth设置了列宽无效的问题
在用到QT的QTableView时,为了显示效果,向手动的设置每一列的宽度,但是如下的代码是无效的。 ui->tableView->setColumnWidth(0,150);ui->tableView->setColumnWidth(1,150);ui->tableView->setColumnWidth(2,150);ui->t…...
【用unity实现100个游戏之10】复刻经典俄罗斯方块游戏
文章目录 前言开始项目网格生成Block方块脚本俄罗斯方块基类,绘制方块形状移动逻辑限制移动自由下落下落后设置对应风格为不可移动类型检查当前方块是否可以向指定方向移动旋转逻辑消除逻辑游戏结束逻辑怪物生成源码参考完结 前言 当今游戏产业中,经典游…...
Docker容器内数据备份到系统本地
Docker运行容器时没将目录映射出来,或者因docker容器内外数据不一致,导致docker运行错误的,可以使用以下步骤处理: 1.进入要备份的容器: docker exec -it <容器名称或ID> /bin/bash2.在容器内创建一个临时目录…...
学信息系统项目管理师第4版系列06_项目管理概论
1. 项目基础 1.1. 项目是为创造独特的产品、服务或成果而进行的临时性工作 1.1.1. 独特的产品、服务或成果 1.1.2. 临时性工作 1.1.2.1. 项目有明确的起点和终点 1.1.2.2. 不一定意味着项目的持续时间短 1.1.2.3. 临时性是项目的特点,不是项目目标的特点 1.1…...
Java发送(QQ)邮箱、验证码发送
前言 使用Java应用程序发送 E-mail 十分简单,但是首先需要在项目中导入 JavaMail API 和Java Activation Framework (JAF) 的jar包。 菜鸟教程提供的下载链接: JavaMail mail.jar 1.4.5JAF(版本 1.1.1) activation.jar 1、准备…...
PostgresSQL----基于Kubernetes部署PostgresSQL
【PostgresSQL----基于Kubernetes部署PostgresSQL】 文章目录 一、创建SC、PV和PVC存储对象1.1 准备一个nfs服务器1.2 编写SC、PV、PVC等存储资源文件1.3 编写部署PostgresSQL数据库的资源声明文件 二、部署PostgresSQL2.1 部署 PV、PVC等存储对象2.2 部署PostgresSQL数据库2.3…...
7 个适合初学者的项目,可帮助您开始使用 ChatGPT
推荐:使用 NSDT场景编辑器快速搭建3D应用场景 从自动化日常任务到预测复杂模式,人工智能正在重塑行业并重新定义可能性。 当我们站在这场人工智能革命中时,我们必须了解它的潜力并将其整合到我们的日常工作流程中。 然而。。。我知道开始使…...
JDBC操作SQLite的工具类
直接调用无需拼装sql 注入依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.43.0.0</version></dependency>工具类 import org.sqlite.SQLiteConnection;/*** Author cpf* Dat…...
SEO百度优化基础知识全解析(了解百度SEO标签作用)
百度SEO优化的作用介绍: 百度SEO优化是指通过对网站的内部结构、外部链接、内容质量、用户体验等方面进行优化,提升网站在百度搜索结果中的排名,从而提高网站的曝光率和流量。通过百度SEO优化,可以让更多的潜在用户找到你的网站&…...
用python实现基本数据结构【03/4】
说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…...
软件测试面试题汇总
测试技术面试题 软件测试面试时一份好简历的重要性 1、什么是兼容性测试?兼容性测试侧重哪些方面? 5 2、我现在有个程序,发现在Windows上运行得很慢,怎么判别是程序存在问题还是软硬件系统存在问题? 5 3、测试的策略…...
网站1g空间多少钱/百度客户端在哪里打开
阅读本文大概需要11分钟。见字如面,我是军哥!这篇文章首发在朋友公号,今天在自己公号发一下,详细记录了我从月薪 1800 到百万年薪到自由职业的全过程,请一定看完,必定对你有价值和启发!1.程序人…...
怎么在电脑上自己做网站/互联网app推广具体怎么做
部署windows服务(1)、建立一个新的windows服务项目Server1 (2)、打开Service1代码视图,找到OnStart部分,加入代码 (3)、切换到设计视图,右键-添加安装程序 (4)、切换到新生成的ProjectInstaller.cs设计视图,找到servic…...
通州个人做网站/友情手机站
目录: (1)axios-响应格式 (2)axios-拦截器 (3)vue2-条件渲染 (4)vue2-列表渲染 (1)axios-响应格式 下面看axios的返回响应对象的内部组成 后…...
做网站横幅的图片/搜索关键词排名提升
推荐一个deep learning绝佳的入门资料 * UFLDL(Unsupervised Feature Learning and Deep Learning)教程http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B 故意把链接地址也写出来,方便看到来源,嘿嘿。 资料写得相当赞&#x…...
网络招商平台网站怎么做/seo排名如何
MySQL DBA全程实战课程 姜承尧老师MySQL数据库44天实战视频教程 MySQL DBA视频课程课程目录(0);目录中文件数:0个(1)姜承尧MYSQL(44天);目录中文件数:0个(2)文档及sql文件;目录中文件数:27个(1) 07.btree.pdf(2) 1.MySQL_Architecture.pdf(3) 1.MySQL数据类型.pdf(4) 1.磁盘 (1…...
绵阳阡陌网站建设/排名app
在实际工程中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。PID控制器问世至今以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,…...