基于事件驱动架构构建微服务第2部分:领域对象和业务规则

原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part2-domain-objects-and-business-rules/

在本文中,我将实现领域模型:

  • EduSync.Speech.Domain

这是包含核心域的最内层。它包含我们的领域对象和业务规则。并定义我们的外部接口。

不允许使用数据库、网络连接、文件系统、UI或特殊框架。

核心领域对自身以外的任何事物一无所知。

这些依赖项及其实现使用接口注入到我们的核心域中。

在上一步结束时,我们最终得到了一个贫血领域模型。所以让我们从丰富它开始。

充血领域模型

贫血领域模型是DDD世界中的一种反模式,因此在本节中,我将使用值对象将领域模型与数据契约分离。

贫血领域模型是一种领域模型,其中数据和对该数据的操作彼此分离。换句话说,只有属性的类和处理这些属性的方法位于另一个类中。

因此,这些其他类既可以读取数据,也可以修改数据。所以领域类必须有public setter。这是缺乏封装反模式。

让我们从验证Title开始。

我的第一个测试是:Title长度必须大于10个字符且小于60个字符:

测试将失败,因此让我们实现Title验证:

Title值对象

实体和值对象的主要区别在于如何识别它们。

实体由引用相等和标识相等标识。

值对象由引用相等和结构相等来标识。

  • 引用相等:如果两个对象引用内存中的同一个对象,则它们相等

  • 标识相等:如果两个对象具有相同的标识,则它们相等

  • 结构相等:如果两个对象的所有成员都相等,则两个对象相等

实体具有Id字段并且是可变的,而值对象没有Id字段并且是不可变的。

值对象没有实体就没有意义,它必须属于一个实体。

考虑以下情况:

  • 2辆相同型号、相同颜色、相同年龄等的车辆……总是2辆不同的车辆,因为每辆车都有自己的标识:车辆是一个实体。

  • 2个所有字段都相等的地址(相同的街道号码、相同的城市、相同的国家,等等)是完全相同的地址:地址是一个值对象。

Title的第一个实现如下所示:

请记住,值对象由引用相等和结构相等来标识.

所以右键单击Title类并选择生成 Equals和GetHashCode。

Title只有一个值,因此选择它并单击确定

Title现在是一个值对象,它的最终实现看起来像这样

这是Title值对象的单元测试。如果它们具有相同的值,我应该验证2个标题是否相等,如果不是,则不同

URL值对象

验证Url的所有逻辑都在名称为UrlValue的值对象中实现

Type值对象

验证SpeechType的所有逻辑都在名称为SpeechType的值对象中实现

Speech领域对象如下所示:

实体和聚合

请记住,实体由引用相等和标识相等标识并具有Id字段。因此,让我们创建一个基本实体类:Entity,并在Id字段上生成Equals和GetHashCode。如果2个实体E1和E2具有相同的id,则 E1==E2应该返回true

DDD聚合是可以作为单个单元处理的领域对象的集群。例如订单及其订单项,它们将是单独的对象,但将订单(及其订单项)视为单个聚合非常有用。

聚合应该始终处于有效状态,并且每个聚合都有一个根是一个实体,不属于该聚合的类只能引用聚合根。

因此,让我们创建一个继承自Entity的基类AggregateRoot,我将其设为泛型,因为T是Id字段的类型,并且它可以根据这些实体而变化 

领域事件

领域事件通过避免直接调用来实现有界上下文之间的通信。所以一个有界上下文B1引发一个事件,一个或多个有界上下文B2…Bn对此事件的子订阅方应该处理该事件以使用它。

因此,让我们创建一个基类DomainEvent 

但是在这里,由于我实施事件溯源的策略,我的有界上下文产生的所有事件都将保存在我的事件存储中。对这些事件感兴趣的其他有界上下文、服务或其他程序将必须订阅服务总线。

比如我每次创建一个新的Speech,然后我都会创建一个SpeechCreatedEvent事件

SpeechCreatedEvent类必须从DomainEvent基类继承 

聚合根的最终实现将如下所示: 

因为Speech实体是聚合根,所以让我们继续从AggregateRoot继承它,Speech实体的Id字段是一个 Guid

让我们添加一些测试来覆盖 domainEvents 

LogCorner.EduSync.Speech.Application和LogCorner.EduSync.Speech.Domain是100%的代码覆盖率 

欢迎关注我的个人公众号”My IO“

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

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

相关文章

qt客户端连接服务器不响应,qt判断tcp客户端是否连接服务器

qt判断tcp客户端是否连接服务器 内容精选换一换本章节指导您使用MongoDB客户端,通过弹性云服务器内网方式连接GaussDB(for Mongo)集群实例。操作系统使用场景:弹性云服务器的操作系统以Linux为例,客户端本地使用的计算机系统以Windows为例。目…

谈谈为什么我们需要云原生架构?

未来的软件,从诞生起,就是生在云上,长在云上的。这个说法绝对不是没有根据的,看看现在的互联网大厂在做的事情,你就知道了:阿里宣布成立云原生技术委员会,并投入数十亿大力推动阿里经济体全面云…

服务器系统设计方案,服务器集群方案设计

当前主流的集群方式包括以下几种:1.服务器主备集群方式服务器主-备方式由一台服务器在正常运行状态提供对外服务,其它集群节点作为备份机,备份机在正常状态下不接受外部的应用请求,实时对生产机进行检测,当生产机停机时…

快别发语音了! | 今日最佳

全世界只有3.14 %的人关注了青少年数学之旅(图源千叶的堕天使绅士猫_呜喵0w0,侵权删)我们无论遇到什么困难,都不要怕,微笑着面对它!消除恐惧的最好方法就是面对恐惧!

软件项目管理概览----版本控制

随着软件项目规模的不断扩大,项目管理的作用变得越来越重要。如果一个需要长期维护的项目不能得到很好的管理与控制,“软件腐败”就会发生,用不了多久,我们的程序可能就会像一团拌好的炸酱面一样难以找到头绪,维护的成…

设计模式之原型

原型模式介绍完整拷贝原型模式主要解决的问题就是创建重复对象,而这部分对象内容本身比较复杂,生成过程可能从库或者RPC接口中获取数据的耗时较长,因此采用克隆的方式节省时间。原型模式是一种创建型设计模式,使你能够复制已有对象…

华为服务器停止响应,windows服务器停止工作

windows服务器停止工作 内容精选换一换无法通过远程桌面连接裸金属服务器时,我们推荐您按照以下思路排查问题。检查是否符合登录条件检查网络是否正常检查防火墙配置是否正常远程访问端口配置异常尝试重启裸金属服务器确认是否已经按照裸金属服务器登录前的准备工作…

专题1.1——Exchange2013部署前准备条件

本专题将主要介绍Exchange2013从部署前准备、正式部署到应用配置和维护的整个过程。博文是我在自己做测试的过程中自己编写的,如果大家有什么意见或问题也欢迎一起讨论交流。废话不多说,下面进入正题。本节将主要介绍部署Exchange2013之前需要准备的先决…

这些让人看瞎了的设计!实力证明,数学才是世界的最终boss!

全世界只有3.14 %的人关注了青少年数学之旅昨天小天刷微博,看到了一组动图,一时间我都不知道是我的眼睛出了错,还是我的大脑反应不过来。奇了怪了!怎么箭头反转了180后,还是原样!问题到底出在哪里&#xff…

你真的了解低代码平台吗?

从 2020 年疫情之后,低代码这个概念就突然变得火热起来,各大自媒体纷纷推出介绍低代码的文章,InfoQ 也曾发表过一篇《为什么我说低代码是“行业毒瘤”?》引发了热议,明道的创始人任向晖随后在自己的公众号写文章《低代…

图像还可以这样玩!如何用OpenCV处理图像?

全世界只有3.14 % 的人关注了青少年数学之旅人工智能近年来呈现爆发式发展,计算机视觉和深度学习作为人工智能的两大支柱学科,近年来得到迅速发展。今天小天将带着大家走进计算机视觉!所谓计算机视觉,就是指用摄影机和电脑代替人眼…

java集合学习笔记 ---Collections类对集合的处理

2019独角兽企业重金招聘Python工程师标准>>> 包名:java.util.CollectionsCollections是个类,不是接口有以下方法,部分列举1.对List进行升序排序public static void sort(List list)如果要进行降序排序,可以在sort函数中制定降序public static…

如何入门.NET Core ? 推荐这10个优秀的开源项目!

.NET 5马上就要发布了,还不知道这些.NET Core开源项目?只推荐干货!当然这些开源项目都是个人或组织开发的。1.Ant Design Blazor.NET进行客户端Web开发又一利器。微软官方认可,微软Build2020开发者大会Blazor介绍中,提…

.NET设计模式(7):创建型模式专题总结(Creational Pattern)

概述 创建型模式,就是用来创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。本文对五种常用创建型模式进行了比较,通过一个游戏开发场景的例子来说该如何使用创建型模式。 为什么需要创建型模式 所…

ABP Vnext 4.4:统一Ef Core的DbContext/移除EF Core Migrations项目

Abp vnext 4.4出现了一个比较重大的变更:在Startup template中移除了EF Core Migrations项目,本文翻译自community.abp.io/articl由于本文发布的时候Abp vnext的版本还没有到4.4,所以本文演示了如何从4.4以前的版本移除EntityFrameworkCore.D…

史上最变态高考数学题,让99%的考生献上膝盖,看完我惊了......

全世界只有3.14 %的人关注了青少年数学之旅今天超模君想问大家一个问题:如果在撒哈拉大沙漠或者是西伯利亚上建造一个大型装置,以便向地球之外的其他星球的朋友们表明地球上存在有智慧的生命,最适当的装置是什么呢?勾股定理&#…

C#操作Excel文件暨C#实现在Excel中将连续多列相同数据项合并

C#操作Excel文件(读取Excel,写入Excel) 看到论坛里面不断有人提问关于读取excel和导入excel的相关问题。闲暇时间将我所知道的对excel的操作加以总结,现在共享大家,希望给大家能够给大家带了一定的帮助。另外我们还要注意一些简单的问题1.exc…

猪肉上的红章和蓝章有啥不同?| 今日趣图

全世界只有3.14 %的人关注了青少年数学之旅亲眼看到金字塔你才会意识到它有多大!(图源光消失的地方,侵权删)你女朋友的脸皮有多厚?(图源程序员新视界,侵权删)猪肉上的红章和蓝章有啥…

如何避免和人尬聊?

全世界只有3.14 %的人关注了青少年数学之旅想要和别人有聊不完的话题?当然是多读书多看新闻了解新鲜有趣的事物啦如果你没有时间去阅读那么关注以下公号将会让你收获更多信息~长按二维码,选择“识别图中二维码”订阅。▼看鉴ID:kanjian6666▲长按二维码“…

java 中的 io 系统总结

Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。 Java 内用 Unicode 编码存储字符,字符流处理类负责将外部的…