美文网首页
实现领域驱动设计-领域事件

实现领域驱动设计-领域事件

作者: marx_yu | 来源:发表于2019-01-01 23:51 被阅读0次

定义

将领域中所发生的活动建模成一系列的离散事件。每个事件都用领域对象来表示。领域事件是领域模型的组成部分,表示领域中所发生的事情。

要点:“领域事件是领域模型的组成部分”,那领域事件是实体还是值对像,还是另一种领域模型呢?从后文的创建“具有聚合特征的领域事件”和具有“身份标识”的领域事件来说,领域事件是一种领域对象,可以是实体也可以是值对像,是另一个层次上的概念。

那应该把领域事件建模为值对像和实体呢?事件直接的理解是“已经”发生的活动,是不变,所以值对像是比较好的选择。

“创建具有聚合特征的领域事件”里说“领域事件并不由聚合中的命令方法产生,而是直接由客户方所发出的请求产生”,即代表一种请求操作的命令,而不是过去发生的事情,并且为了区分不同的请求或去重,而分配唯一身份标识,而成为聚合(实体)。但其实从另一方面理解,这些事件代表着已经发生的请求(这些不是领域内的,但也是整个系统中已经发生的活动),所以即使这时候事件建模成聚合也有资源库,但也不应该去修改或删除领域事件的

多个限界上下文和领域事件

“事件订阅方不应该在另一个聚合上执行命令方法,因为这样将破坏在单一事务中只修改单个聚合实例的原则”,这里的事件订阅方是指“同步”的订阅方,即在发布方同一个线程执行的,从领域方面理解是同一个子域的。那如果是不同子域或不同限界上下文呢?那肯定可以,但这时候应该是使用异步事件的,并且是以“所有聚合实例之间的最终一致性”为目标的,这也是目前最流行的使用分布式的消息中间件进行系统集成和解耦的方式,而这一般也用在远程的限界上下文。

这种情况下,消息设置的一致性确实是困难的,书中提到的“共享持久存储”或“全局的XA事务”或“位于单个本地事务中”,这些方法在实际工程是很难完成的,因为系统复杂和访问量的增长,RDB和原子性事务就会是瓶颈,所以在使用分布式消息中间件的情况,是使用事务补偿的方式来解决这问题的,比如重试,Write Ahead Log+补偿

而自治服务的思想“相互独立的完成各自的功能……自治服务可以避免对远程过程调用(RPC)的使用,这可以带来更高程度的独立性,这种思想非常值得借鉴,服务自治性越好,稳定性越好保证,但分布式和微服务盛行的互联网化企业应用中,RPC几乎的不可避免的,那怎么办呢?关键路径的RPC需要有降级熔断机制,来减少远程系统对本地服务的影响。

另外异步事件的方式,时延也是不可避免的,需要注意

事件存储

事件存储的几个应用场景:

1.将事件存储作为一个消息队列来使用。当前留下的Kafka消息中间件,就是消息存储和消息队列一体的,跟事件存储这种思想如出一辙

2.存储由模型的命令方法所产生的所有结果的历史记录,用于跟踪bug,记录审计日志

3.使用事件存储中的数据来进行业务预测和分析

4.从资源库中获取一个聚合实例时,使用事件来重建该聚合实例

5.撤销对聚合的操作,即在重建聚合时过滤掉某一些事件

把聚合实例处理成一序列事件存储的记录的重建,在存储方案上是简单的,由于事件是不对的,所以一致性也比较好保证,但重建逻辑是比较复杂的,处理消耗也比较大。

额外的技术点:

对于需要在不同限界上下文中传输的对象,一般需要通过序列化和反序列化转换的,都不建议提供重载的equals和hashCode方法,因为反序列化后对象定义会改变,比如json和xml的序列化方法

通过REST发布领域事件或变化通知的,或者其他资源的,如果可以一段时间内不变的,可以直接使用类似Cache-Control:max-age=3600的缓存控制头,使得浏览器自动进行缓存。

对于事件消重,在发布方或在领域对象(即事件对象)上实现幂等是“太困难,太不实用,甚至不可能的”,所以都是在订阅方实现幂等的,即在消息消费者实现去重或支持幂等的

问题

P262 “最好的方式是将事务处理委派给应用服务,这是一种很自然的选择”,这个真不理解,事务为什么委派给应用服务

P270 “聚合的一大原则:在一个事务中,只对一个聚合进行修改”,如果修改的是同一个聚合行吗?我的理解,应该是可以的,一般聚合的修改是在一个独立的资源库,而在一个事务里一个资源库里多次修改一个聚合,并没违反什么规范。

相关文章

  • 实现领域驱动设计-领域事件

    定义 将领域中所发生的活动建模成一系列的离散事件。每个事件都用领域对象来表示。领域事件是领域模型的组成部分,表示领...

  • 读《领域驱动设计》有感

    写完《DDD领域驱动设计初探》后,教主推荐了两本领域驱动设计的书--《领域驱动设计》和《实现领域驱动设计》,...

  • 1.复杂系统中采用DDD-lite实现模糊需求--开篇

    一、序 2015年底初识DDD(领域驱动设计),阅读和学习《领域驱动设计》By Eric和《实现领域驱动设计》By...

  • DDD落地过程中关于领域事件的设计

    前言 领域事件是领域驱动设计中的重中之重,事件风暴的时候确认的领域事件可以直接应用在我们的代码设计中,但是领域事件...

  • 领域驱动设计DDD

    最近在换工作,利用间隙看了两本领域驱动设计的经典书籍:《领域驱动设计:软件核心复杂性应对之道》,《实现领域驱动设计...

  • DDD 领域驱动设计学习(三)- 领域事件

    领域事件(Domain Event) 在Eric的《领域驱动设计》中并没有提到领域事件,领域事件是在后来才被正式提...

  • 日更十七

    DDD领域驱动设计中领域事件(Domain Event)约定 领域事件是领域实体发生状态变化后,向外界发布(pub...

  • 实现领域驱动设计-领域服务

    领域服务定义 先看看领域服务的定义:领域中的服务表示一个无状态的操作,它用于实现特定于某个领域的任务。当某个操作不...

  • 《领域驱动设计精粹》读书笔记

    《领域驱动设计精粹》的作者Vaughn Vernon同样也是《实现领域驱动设计》的作者。书中精炼的概括了《DDD》...

  • 本周读书复盘

    1.《实现领域驱动设计》 DDD领域驱动设计这几年在软件设计领域非常火,特别是进来软件的业务需求日益复杂,软件规模...

网友评论

      本文标题:实现领域驱动设计-领域事件

      本文链接:https://www.haomeiwen.com/subject/kxnolqtx.html