真实世界的映照-DDD实体

什么是实体?

实体,官方的解释是:实体(Entity,又称为Reference Object)很多对象不是通过他们的属性定义的,而是通过一连串的连续事件和标识定义的。主要由标识定义的对象被称为ENTITY。

但,这官方的解释,反而将实体玄奥起来了。

很书籍、博客上说,实体一定是具有唯一标识(ID),于是很多人便认为,有唯一标识的就是实体。然而,值对象,也可以有唯一标识。

也有人说,实体与数据库表一一对应,那么,只要是要与数据库做映射的,都是实体。然而,值对象,也可以与数据库表映射。

其实,实体的定义很简单:

实体是有生命周期,能演变,里面的属性值可以随时变化。简单的说,实体有类似set方法,可以在任何时候修改实体的属性。

只要是符合这个本质的,都可以称之为实体。

实体的特征

1、具有唯一标识(世界上没有相同的两片绿叶)

2、具备生命周期,在生命周期内其内部属性可以被改变

3、实体具有行为方法

DDD为啥要提出实体这个概念?

试想一下,我们传统开发的时候,是怎么进行建模的?

我相信,大多团队,都是直接在数据库里面建一张表,就完事了吧。

好一点的团队,会使用PowerDesigner之类的工具构建出物理模型。

再好一点的团队,会构建出逻辑模型,然后通过逻辑模型再生成物理模型。但更多的人会认为逻辑模型是个多余,因为项目一个确定,所使用的数据库就基本已经确定,直接设计物理模型,不香么?

再回想,以上的这些方式设计出来的模型,是不是基本上只有开发人员在参与?因为,业务人员也看不懂这些。

再回想,只有开发人员参与得出的模型,真的是符合业务的模型吗?真的是符合实现世界的模型吗?

很可惜,只有开发人员参与得出的模型,往往只能满足当时的业务需求,一当业务需求发生改变时,这模型便不符合了,严重的,会导致整个项目需要大重构才能满足新的业务需求。

难怪,会有如此多的项目推翻重构,从1.0系统到5.0系统,每一次都是推翻前者进行重构开发。

实体是模拟真实的物理世界,是连接开发人员与业务人员的重要工具。

DDD提倡的是用模型来模拟现实的物理世界,只有符合现实物理世界的模型才是好的模型。

在DDD中,实体与值对象是领域进行建模的重要工具。

实体与贫血模型、充血模型

在实体中,如果只有简单的get、set方法,那么实体表现就是贫血模型。如果实体中有着丰富的行为方法,那么实体表现就是充血模型。

很多DDD的书,都推荐使用充血模型,而反对贫血模型。然而,在工程实践中,往往发现贫血模型更加好用,充血模型使代码看上去臃肿不堪。

首先,需要申明的是,实体与数据库不是映射关系!实体的持久化,不一定得持久到到数据库中,实体可以持久化到文件中、缓存中、甚至内存中!!

而PO(persistant object)才是与数据库一一映射的对象。

在PO中适合贫血模型,在实体中适合充血模型。实体与PO,只通过资源库关联起来。

实体的持久化是通过资源库而实现的,而资源库的具体实现,则是通过依赖倒置和依赖注入的方式在基础设施层实现,PO放在基础设施层与数据库一一映射。实体中丰富的行为方法,操作着资源库对象,通过资源库对象操作着PO对象,直到将数据写入数据库。

如何践行实体?

物理世界中的每一个物体、每一个概念,都与一个实体一一对应。

比如,在线上图书馆中,书籍得对应书箱实体。书籍有编号(唯一标识)、书名、作者、出版社、出版时间、售价、封面、内容等属性,有借出、归还、上架、下架等动作。书籍的生命周期是入库到出库时间段。在物理世界中的书籍对应数字世界中的书籍实体,也是具有和物理世界一样的属性、动作、生命周期。

实体的建模,可以由业务人员来完成,也可以由开发者与业务人员一起完成。

设计实体的工具,可以用简单的Excel表格,也可以用专业的UML软件,甚至,可以在白纸上画一些简单的示意图!

注意的是,实体的唯一标识,不一定是数据库的主键,虽然很多实际上的做法,数据库主键都是等于实体的唯一标识。

注意的是,如果一个物理世界的事物,更适用使用值对象来建模,那么,请使用值对象。DDD的原则是,能用值对象尽量用值对象,不能用值对象时再考虑实体。

注意的是,实体是处于设计阶段,不要急迫地把实体变成代码!因为,你设计好的实体,需要与业务人员一起审核,在审核过程中,业务人员会提出他的问题,指出模型中的缺陷,或者增加一些模型。

注意的是,如果一个实体在真实世界中找不到对照,那么这个实体就肯定是有问题的,需要考虑是否要把实体删除。

import org.ddd.book.domain.book.repository.IBookRepository;
import org.ddd.book.domain.book.vo.AuthorVO;
import org.ddd.book.domain.book.vo.PublisherVO;
import org.ddd.book.domain.factoty.RepositoryFactory;import java.util.Date;/*** 书籍实体*/
public class BookEntity {// 书籍ID(编号)private Long bookId;// 书籍名称private String bookName;// 作者private AuthorVO author;// 出版社private PublisherVO publisher;// 出版时间private Date publishDate;// 售价private Long price;// 封面private String headImg;// 内容private BookContentEntity bookContent;// 持久化public void save() {RepositoryFactory.get(IBookRepository.class).save(this);}// 上架public void down() {}// 下架public void up() {}// 借出public void lend() {}// 归还public void returnBack() {}
}

了解更多,请关注公众号:jgssy01

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

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

相关文章

RTThread studio 驱动开发

rtthread 驱动使用的两种情况 rtthread studio 自动生成 由 RT Thread Studio 自动生成,无需修改任何文件或者简单定义几个宏即可直接使用的驱动,如 GPIO,UART,I2C,SPI,SDIO 和 ETH 等。 使用 RT-Thread S…

嵌入式硬件中常见的面试问题与实现

1 01 请列举您知道的电阻、电容、电感品牌(最好包括国内、国外品牌) ▶电阻 美国:AVX、VISHAY威世 日本:KOA兴亚、Kyocera京瓷、muRata村田、Panasonic松下、ROHM罗姆、susumu、TDK 台湾:LIZ丽智、PHYCOM飞元、RALEC旺诠、ROYALOHM厚生、SUPEROHM美隆、TA-I大毅、TMT…

STM32学习和实践笔记(6):自己进行时钟配置的思路

在《STM32学习和实践笔记(4): 分析和理解GPIO_InitTypeDef GPIO_InitStructure (d)-CSDN博客》 中,我了解到,在程序执行我们写的main函数之前,实际上先执行了一个汇编语言所写的启动文件,以完成相应的初始…

TCP协议简单总结

TCP:传输控制协议 特点:面向连接、可靠通信 TCP的最终目的:要保证在不可靠的信道上实现可靠的传输 TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接 三次握手建立可靠…

【刷题篇】回溯算法(二)

文章目录 1、求根节点到叶节点数字之和2、二叉树剪枝3、验证二叉搜索树4、二叉搜索树中第K小的元素5、二叉树的所有路径 1、求根节点到叶节点数字之和 给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表…

网络安全---Packet Tracer - 配置扩展 ACL

一、实验目的 在Windows环境下利用Cisco Packet Tracer进行 配置防火墙操作。 二、实验环境 1.Windows10、Cisco Packet Tracer 8.2 2.相关的环境设置 在最初的时候,我们已经得到了搭建好的拓扑模型,利用已经搭建好的拓扑模型,进行后续的…

【AAOS车载系统+AOSP14系统攻城狮入门实战课】:正式上线了(二百零三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

B02、分析GC日志-6.3

1、相关GC日志参数 -verbose:gc 输出gc日志信息,默认输出到标准输出-XX:PrintGC 输出GC日志。类似:-verbose:gc-XX:PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志, 并在进程退出时输出当前内存各区域分配情况-XX:PrintGCTimeStamp…

K8S容器空间不足问题分析和解决

如上图,今天测试环境的K8S平台出现了一个问题,其中的一个容器报错:Free disk space below threshold. Available: 3223552 bytes (threshold: 10485760B),意思服务器硬盘空间不够了。这个问题怎么产生的,又怎么解决的呢…

springboot+vue2+elementui+mybatis- 批量导出导入

全部导出 批量导出 报错问题分析 经过排查,原因是因为在发起 axios 请求的时候,没有指定响应的数据类型(这里需要指定响应的数据类型为 blob 二进制文件) 当响应数据回来后,会执行 axios 后置拦截器的代码&#xff0…

Linux内核映像vmlinux、Image、zImage、uImage,system.map区别

编译好内核后,一般都会生成标题中的各种文件,这些文件都有什么不同呢? vmlinux(elf文件) vmlinux:Linux内核编译出来的原始的内核文件,elf格式,未做压缩处理。 该映像可用于定位内…

JVM—垃圾收集器

JVM—垃圾收集器 什么是垃圾 没有被引用的对象就是垃圾。 怎么找到垃圾 引用计数法 当对象引用消失,对象就称为垃圾。 对象消失一个引用,计数减去一,当引用都消失了,计数就会变为0.此时这个对象就会变成垃圾。 在堆内存中主…

基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba并采用前后端分离的企业级微服务多租户系统架构

简介 基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba并采用前后端分离的企业级微服务多租户系统架构。并引入组件化的思想实现高内聚低耦合并且高度可配置化,适合学习和企业中使用。 真正实现了基于RBAC、jwt和oauth2的无状态统一权限认证的解决方案&#x…

天池医疗AI大赛[第一季] Rank5解决方案

一、赛题说明 数据格式 本次大赛数据集包含数千份高危患者的低剂量肺部CT影像(mhd格式)数据,每个影像包含一系列胸腔的多个轴向切片。每个影像包含的切片数量会随着扫描机器、扫描层厚和患者的不同而有差异。原始图像为三维图像。这个三维图…

C++设计模式:抽象工厂模式(七)

1、定义与动机 抽象工厂定义:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类动机: 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,…

从ChatGPT到多模态大模型:现状与未来(多模态)

ChatGPT 训练的核心技术主要包括: 预训练语言模型;有监督微调;基于人类反馈的 强 化 学 习 (ReinforcementLearningfrom Human Feedback,RLHF) 首先,通过自监督预训练使语言模型从大规模语料库中学习语言规律,具备基础 理解和生成能力;然后,通过构造指令微调数据集 并对模型进…

uniapp在发行原始云打包ios时提示私钥证书不是有效的p12文件

uniapp在发行原始云打包ios时提示私钥证书不是有效的p12文件 解决方法: 经过我多次的创建p12证书文件,然后更换设备继续创建,仍然存在这个问题,通过排查不是.p12的本身的问题,而是命名的问题,命名不能是中…

数据仓库的概念和作用?如何搭建数据仓库?

随着企业规模的扩大和数据量的爆炸性增长,有效管理和分析海量数据成为企业数字化转型的关键。而在互联网的普及过程中,信息技术已深入渗透各行业,逐渐融入企业的日常运营。然而,企业在信息化建设中面临了一系列困境和挑战&#xf…

MKS GHW-12 RF Plasma Generator Genesis 使用说明

MKS GHW-12 RF Plasma Generator Genesis 使用说明

云平台和云原生

目录 1.0 云平台 1.1.0 私有云、公有云、混合云 1.1.1 私有云 1.1.2 公有云 1.1.3 混合云 1.2 常见云管理平台 1.3 云管理的好处 1.3.1 多云的统一管理 1.3.2 跨云资源调度和编排需要 1.3.3 实现多云治理 1.3.4 多云的统一监控和运维 1.3.5 统一成本分析和优化 1.…