基于事件驱动架构构建微服务第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,一经查实,立即删除!

相关文章

/etc/sudoers中的含义

Sudo 是允许系统管理员让普通用户执行一些或者全部的root 命令的一个工具,如halt,reboot,su 等等。这样不仅减少了root 用户的登陆 和管理时间,同样也提高了安全性。Sudo 不是对shell 的一个代替,它是面向每个命令的。…

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

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

asp版新闻发布今日弄好

感谢组长帮忙弄好了新闻发布的删除功能,组长自己那么多事,而且又是凌晨二点,仍过来帮我解决问题。太感激了。。。。最近特别忙,也让我多了些怨天尤人的感慨。其实还是自己的原因,如果我能力足够强的话,会轻…

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

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

用SQL Server Compact Edition创建移动应用程序 【转载】

本文转载自 http://www.bccn.net/Article/sjk/sqlserver/jszl/200709/6545.html 这个文档比较完整地介绍了在移动开发中,如何实现对SQL Server数据库的合并订阅。收藏一下先,在用的时候仔细看一下即可。转载于:https://www.cnblogs.com/chenxizhang/arch…

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

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

第2天.make的学习(第二部分)对伪目标的理解

一、目标,依赖,命令也许大家觉得这个不重要,但今天我有了新的认识,所以写了下来。这三个就是Makefile的全部,但今天我要重点说一下它的执行顺序。每个Makefile都有且只有一个终极目标,下设若干子目标&#…

ASP.NET(c#)常用类函数

常用函数系列: public static string Get_ClientIP() 得到客户端IP public static string Get_CMac(string IP) 得到客户端 CMac 地址 public static string RequestF(string xPName,string xPType,int xLenDef) 安全接收数据系列 public static string Show_Cont(string xStr)…

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

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

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

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

设计模式之原型

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

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

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

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

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

Tabs

Tabs控件的功能是在一个页面上显示多个选项卡。由两部分组成:TabContainer和TabPanel.前者表示整个一组选项卡,而后者表示其中的一个选项卡。 属性列表: OnClientActiveTabChanged:单击选项卡标题触发的事件 Height:选项卡的高度 ContentTemp…

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

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

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

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

服务器抽屉式维护,一种服务器用可顺序运动的滑轨

1.一种服务器用可顺序运动的滑轨,包括内轨(1)、中轨(2)和外轨(3),内轨(1)、中轨 (2)和外轨⑶依次连接,其特征在于:还包括外壳⑷,外壳⑷内设有滑行架(5),滑行架 (5)与外轨(3)相连接,中轨(2)上设有…

50个常用sql语句

Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题: 1、查询“001”课程比“002”课程成绩高的所有学生的学号; select a.S# from (select s#,score from SC where C#001) a,(selec…

无边工作,无际遐想

又是一个胡乱涂鸦,最近很长一段时间我就像临产孕妇样,挣扎在“生产”边缘,每次将手放在键盘上,努力憋出一丝一缕。却就是伸不出个头来。还好,我比孕妇自由,可以停下来休息休息。有句话说的好:生…

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

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